Need Scripting Help
David M. Carney
carney1979 at gmail.com
Mon Jan 10 03:10:31 UTC 2005
On Mon, 10 Jan 2005 12:39:19 +1100, Cameron Hutchison
<camh+ubuntu at xdna.net> wrote:
> Once upon a time David M. Carney said...
> >
> > As the script is written, it works just fine on any file with no
> > spaces in the filename. However, it fails with any files with spaces
> > in the filename.
> >
> > #!/bin/bash
> > #
> > for I in `echo $*`
> > do
> > exec gnome-terminal --command="bcrypt "$I
> > done
>
> change this to:
>
> for I in "$@"
> do
> exec gnome-terminal --command="bcrypt \"$I\""
> done
>
> There are three places in this script where you need to be aware of
> spaces in filenames.
>
> 1) for I in `echo $*`
>
> After `echo $*` is expanded, the for loop will split it on space
> boundaries. This will break file names with spaces. Furthermore,
> `echo $*` is redundant, since just $* will do the same without invoking
> another process.
>
> Put quotes around the $* and the spaces in filenames will be
> preserved. eg. "$*". Finally, use "$@" which is similar to "$*" but
> technically more correct - see the bash man page for differences.
>
> 2) Expansion of $I in the loop
>
> After getting word expansion correct in the argument list to the "for"
> command, you need to expand the variable properly. This almost always
> entails enclosing the expansion in double quotes: "$I", otherwise the
> spaces will not be preserved. In a simpler case than yours, if the loop
> contained:
> ls -l $I
> and the filename was "foo bar", the command would expand to:
> ls -l foo bar
> which would try to list two separate files. So you need:
> ls -l "$I"
> which expands to
> ls -l "foo bar"
> Sometimes you dont notice the difference because it can be subtle. For
> example: I="foo bar" (two spaces):
> echo $I -> echo foo bar
> This outputs "foo bar" (one space) unless you enclose $I in double
> quotes.
>
> 3) Expansion of arguments by gnome-terminal
>
> When gnome-terminal runs it's command, you need quotes in the right
> places otherwise it will break filenames with spaces. You need to escape
> the quotes so the "exec" command in the for loop does not consume the
> quotes. gnome-terminal will then get a single argument that contains:
> --command=bcrypt "foo bar"
> If those quotes weren't there, bcrypt would think there were to files to
> encrypt.
>
> All in all, spaces in filenames are a real pain to handle properly with
> the shell, particularly when you have multiple levels of evaluation like
> you have Often when writing scripts like this, it takes me a little
> trial and error to get everything right. Dont be put off if you dont get
> it first go.
>
> --
> ubuntu-users mailing list
> ubuntu-users at lists.ubuntu.com
> http://lists.ubuntu.com/mailman/listinfo/ubuntu-users
>
Wow. A lot I don't really understand, but I'm going to save your reply
and re-read it again later.
Of course, it worked, and thank you very much!
David
--
Registered Linux User #297958
More information about the ubuntu-users
mailing list