[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: shell escape problem?



On Fri, Apr 08, 2005 at 04:51:58PM -0400, Matt Price wrote:
> I've written a little shell that generates this string and calls it
> $CMD: (sorry no line breaks):
> 
> multi-gnome-terminal --add-window -T --tname==.teaching/ --tcommand="mutt -f =.teaching/" -T --tname==.moin/ --tcommand="mutt -f =.moin/" -T --tname==.mycroft --tcommand="mutt -f =.mycroft" -T --tname==.evilbitch --tcommand="mutt -f =.evilbitch" -T --tname==.bibliography/ --tcommand="mutt -f =.bibliography/" -T --tname==.dufferin-grove --tcommand="mutt -f =.dufferin-grove" -T --tname=+.Carfreeday --tcommand="mutt -f +.Carfreeday" -T --tname=+.IN_xml_openoffice --tcommand="mutt -f +.IN_xml_openoffice" -T --tname=+.IN_Pessimism --tcommand="mutt -f +.IN_Pessimism"
> 
> when I type this command in manualy, it executes perfectly.  But when
> I try to execute this line in the script:
> $CMD
> 
> I get an error 
> "Error on option -f: unknown option.

If you have some shell variable and want to execute its content as if
it had been typed on the commandline, you need to use an "eval":

eval $CMD

Otherwise, the double quotes will not be removed/interpolated.

To debug such problems yourself next time, you could write a little
script like this

#!/usr/bin/perl
$,="\n";
print @ARGV,'';

and name it "showargs", for example.  It will simply display the
arguments exactly as it receives them, each one on a separate line, so
can quickly diagnose what the problem is.

An example ("./showargs" replaces "multi-gnome-terminal" here):
Typing the following on the commandline (one line), it would print:

$ ./showargs --add-window -T --tname==.teaching/ --tcommand="mutt -f =.teaching/"
--add-window
-T
--tname==.teaching/
--tcommand=mutt -f =.teaching/

But if you assign the above commandline to $CMD, and call it like you
did, you'd get:

#!/bin/sh
CMD='./showargs --add-window -T --tname==.teaching/ --tcommand="mutt -f =.teaching/"'
$CMD

--add-window
-T
--tname==.teaching/
--tcommand="mutt
-f
=.teaching/"

As you can see, the -f now is a seperate argument, that's why
multi-gnome-terminal complained...

If you use eval, everything is fine again:

#!/bin/sh
CMD='./showargs --add-window -T --tname==.teaching/ --tcommand="mutt -f =.teaching/"'
eval $CMD

--add-window
-T
--tname==.teaching/
--tcommand=mutt -f =.teaching/


The details are all explained in the bash manpage -- better than I ever
could do... ;)

Almut



Reply to: