From john.sturdy at ul.ie Wed Mar 10 14:38:46 2010 From: john.sturdy at ul.ie (John.Sturdy) Date: Wed, 10 Mar 2010 14:38:46 -0000 Subject: [prog] Project announcement (if that's on-topic for this list) Message-ID: Hi, I can't see anything in the mailing list notes to say whether or not this on topic -- let me know if it isn't! As a spinoff from my paid work project, I've written a library that provides a common API to multiple scripting languages. I've made it into a separate project, as I thought it could be useful for projects other than my own -- if used in place of interfacing an application directly to a scripting language, it lets the user make the choice of what language to script the application in, at run time. I'm just starting to publicize it, and felt more comfortable about announcing it on a list with a "be nice" ethos first, before I submit it to freshmeat a bit later. If anyone's interested, it's at http://www.nongnu.org/muesli/ My apologies if that's off-topic for this list, __John From mim at miriam-english.org Mon Mar 29 02:07:01 2010 From: mim at miriam-english.org (Miriam English) Date: Mon, 29 Mar 2010 12:07:01 +1000 Subject: [prog] getting parameters into scripts Message-ID: <4BB00B45.4030001@miriam-english.org> I normally use positional parameters in scripts, collecting them as $1, $2, $3, and so on. This is fine, but I recently wrote a script where it would have been really nice to be able to give the parameters in a different order under certain circumstances. I filed that away in my head until this morning I hit on the idea of doing something like this: for i in $@; do eval "$i" done If I give all parameters in the form a=blah or x=nerf then this little loop stores the value into a variable called $a or $x in the script. This works wonderfully regardless of how many parameters it is fed, automatically adapting to how many are given. My problem is that it trips up if I feed it a parameter with a space in it. For example if my script is called testparams and I invoke it this way: testparams c=turkey a="elephant trunk" b="blob" d='pine cone' then all variables are stored, but $a contains just "elephant" and $d contains just "pine". Weirdly, $2 is "a=elephant trunk" and $4 is "d=pine cone", just as you'd expect. Add this after the above little loop and you'll see what I mean: echo "named:" echo $a echo $b echo $c echo $d echo "positional:" echo $1 echo $2 echo $3 echo $4 Looking at $@ displays the problem. The quotes have been lost: c=turkey a=elephant trunk b=blob d=pine cone so it looks like we have 6 items, even though $# knows there are only 4. So I tried a different tack: for i in $(seq $#); do and noticed that putting echo $`echo $i` inside the loop printed out "$1", "$2", and so on, so I tried (hold onto your hat) evaluating that with: eval `eval "echo $\`echo $i\`"` but was back to the same old problem again. [sigh] Anybody know how to get parameters with spaces into those variables? Or should I just give up on trying to be a mental contortionist? :) -- If you don't have any failures then you're not trying hard enough. - Dr. Charles Elachi, director of NASA's Jet Propulsion Laboratory ----- Website: http://miriam-english.org Blog: http://miriam_e.livejournal.com From chris+linuxchix at aptivate.org Mon Mar 29 08:53:15 2010 From: chris+linuxchix at aptivate.org (Chris Wilson) Date: Mon, 29 Mar 2010 10:53:15 +0200 (CEST) Subject: [prog] getting parameters into scripts Message-ID: Hi Miriam, On Mon, 29 Mar 2010, Miriam English wrote: > I normally use positional parameters in scripts, collecting them as $1, > $2, $3, and so on. This is fine, but I recently wrote a script where it > would have been really nice to be able to give the parameters in a > different order under certain circumstances. [...] > testparams c=turkey a="elephant trunk" b="blob" d='pine cone' What about using options with getopt, e.g. testparams --c=turkey --a="elephant trunk" That would be much, much more standard. > then all variables are stored, but $a contains just "elephant" and $d > contains just "pine". Weirdly, $2 is "a=elephant trunk" and $4 is > "d=pine cone", just as you'd expect. Probably because of the eval. > Looking at $@ displays the problem. The quotes have been lost: > c=turkey a=elephant trunk b=blob d=pine cone They are used by the shell to work out the arguments to your script, and then removed. I.e. they have a special meaning to the shell, just like backticks and $. > so it looks like we have 6 items, even though $# knows there are only 4. Only if you try to break them at spaces. You still have $1 == "elephant trunk". But if you expand $@, it just concatenates them all together, separated by spaces, and of course there are no quotes then. How about: eval `echo $i | sed -e 's/=/="/' -e 's/$/"/'` which turns: a=elephant trunk into: a="elephant trunk" and then evaluates that? > Anybody know how to get parameters with spaces into those variables? > Or should I just give up on trying to be a mental contortionist? :) Try getopt. Cheers, Chris. -- Aptivate | http://www.aptivate.org | Phone: +44 1223 760887 The Humanitarian Centre, Fenner's, Gresham Road, Cambridge CB1 2ES Aptivate is a not-for-profit company registered in England and Wales with company number 04980791. From johnc+linuxchix at kirriwa.net Mon Mar 29 23:30:26 2010 From: johnc+linuxchix at kirriwa.net (John Clarke) Date: Tue, 30 Mar 2010 10:30:26 +1100 Subject: [prog] getting parameters into scripts In-Reply-To: <4BB00B45.4030001@miriam-english.org> References: <4BB00B45.4030001@miriam-english.org> Message-ID: <20100329233026.GA13986@kirriwa.net> On Mon, Mar 29, 2010 at 12:07:01PM +1000, Miriam English wrote: Hi Miriam, > head until this morning I hit on the idea of doing something like this: > > for i in $@; do > eval "$i" > done [snip] > Anybody know how to get parameters with spaces into those variables? Well, this works the way you want, but only for parameters of the form var=value: for i in "$@" do i=`echo $i|sed -e 's/=\(.*\)/="\1"/'` eval $i done It restores quotes around everything after the equals sign before the eval is done. Note the quotes around $@, this is essential to get the behaviour you want. You could use bash's built-in pattern substitution if you want. Instead of the sed command, use this: i="${i/=/=\"}\"" (a bit ugly because bash doesn't support back-references, so the closing quote has to be added after the pattern substitution) If you wanted to only eval parameters of the form var=value, try this (bash only): shopt -s extglob for i in "$@" do case $i in +([[:word:]])=*) i=`echo $i|sed -e 's/=\(.*\)/="\1"/'` eval $i ;; *) # do whatever you want with other parameters here ;; esac done (remove the shopt and replace "+([[:word:]])=*" with "*=*" if you need to use sh). > Or should I just give up on trying to be a mental contortionist? :) Think of it as a learning experience :-) John -- > Cars _are_ hardware. If you can kick it, without it caring, it's hardware. Funny, I always thought my boss fell into the category of "wetware." -- Dave Buckles