shell script question

bscott at ntisys.com bscott at ntisys.com
Mon Jan 20 12:14:49 EST 2003


On Mon, 20 Jan 2003, at 8:38am, eprice at ptc.com wrote:
> for i in `ls`; do "`which du` -khs $i"; done

  First, a pet peeve of mine: Use

	for i in * ;

instead of

	for i in `ls` ;

Both generate a list of filenames, but the later needless invokes an
external process to do so.  The shell is perfectly capable of generating a
file list all by itself.  :)

  Now, on to your real problem.  The for loop is basically correct.  If we
look at the part inside the "do ... done" construct, we see that this
command will be executed:

	"`which du` -khs $i"

  It is essential to understand that shell parsing is built upon splitting a
command line up into "words", separated by spaces.  Each word is then
interpreted individually.  Placing a series of characters into single or
double quotes turns that series of characters into a single word.  Since the
first word in an otherwise normal command line is interpreted as the command
to run, the system will treat the entire above construct as the name of a 
command to run.

  Inside double quotes, certain expansions (in this case, variable and 
back-quote expansion) are still done.  The output of

	which du

is used to replace the back-quote construct.  And the

	$i

is replaced with the loop value for each iteration of the for loop.  So, 
after expansion, the command might look like this:

	"/bin/du -khs bak"

Since that is enclosed in double-quotes, the shell is going to consider it a 
single word, and look for a command with that exact string for a name 
(spaces and all).  Obviously, such a command does not exist, so you get the
errors you see.

  A corrected version of your original might be:

	for i in * ; do du -khs "$i" ; done

  The loop variable is placed in double-quotes to make sure the "du" command
sees it as a single word.  Otherwise, if one of your directories contained
spaces or other shell meta-characters, it would get mangled by the shell
before it got passed to "du".  The rest of the command ("du" and "-khs")  
you want parsed as individual words so they get handled by the shell as the
command to run and said command's arguments, respectively.

  Hope this helps,

-- 
Ben Scott <bscott at ntisys.com>
| The opinions expressed in this message are those of the author and do not |
| necessarily represent the views or policy of any other person, entity or  |
| organization.  All information is provided without warranty of any kind.  |




More information about the gnhlug-discuss mailing list