X-mailer: m, by Cameron Simpson Date: Thu, 25 Mar 1999 23:03:16 +0000 Subject: Re: Linuxconf and Bash-2.0 script References: <36FA8A08.2D53960@ohiocounty.net> To: redhat-list@redhat.com CC: Robert W. Canary From: Cameron Simpson Reply-to: cs@zip.com.au Errors-to: cs@zip.com.au Return-receipt-to: cs@zip.com.au Organization: Canon Information Systems Research Australia, Sydney, Oz On 26 Mar 1999, in message <36FA8A08.2D53960@ohiocounty.net> "Robert W. Canary" wrote: | Hi have some bash conflicts going on here .... These are generic shell conflicts, not bash specific. | The commandline arguments are not being read correctly. If any of the | arguments a set of singal quotes (''). Then bash interrupts them as a | blank. Thus when I do 'exec usernew $*' I pass: | usernew -m -c -d /home/newboy -s /bin/bash -G newboy | it should be : | usernew -m -c '' -d /home/newboy -s '/bin/bash' -G '' newboy [...] | Is there something special I need to do here ? The command line arguments are being read correctly - they're just not being _passed_in_ correctly. In the shell: $* All arguments, but like any other variable, space interpretation is done, which breaks them up and of course "vanishes" the empty ones. "$*" All arguments, not space interpretation (but that of course turns it into _one_ argument - not what you want) $@ Just like $* "$@" All arguments, correctly quoted. This is a special piece of magic intended expressly for passing the argument list to other commands intact. So, "$@" is what you want - almost. There's a historical bug with this of long standing. If you have no arguments at all, "$@" is the same as "" (i.e. a single empty argument - no what you want). I imagine the reasoning was that you've got a quoted thing there and it mustn't just vanish, but generally it's not what you want. So, we reach for parameter stuff and read in the manual (man sh): Parameter Substitution [...] ${parameter:+word} If parameter is set and is non-null, substitute word; otherwise substitute nothing. [...] If the colon (:) is omitted from the above expressions, the shell only checks whether parameter is set or not. So the incantation you really want is: ${1+"$@"} This says "if $1 is defined (==> we have more than zero arguments) insert "$@", otherwise insert nothing". And lo, the "$@" problem with no arguments is worked around. Learn it - love it. It is the standard robust way to pass your current argument list to a subcommand. You now want to say: exec usernew ${1+"$@"} Simple and robust. -- Cameron Simpson, DoD#743 cs@zip.com.au http://www.zip.com.au/~cs/ Technique will get you through times of no strength a lot better than strength will get you through times of no technique. - the Nealomatic