Correct quoting to pass a shell variable to perl

82 views Asked by At

I'm trying to spawn some dummy processes. The /path/to is the same for each, but I can't seem to get the DAEMON name to print. The result using the code below is 2 processes called /path/to/. How can I achieve /path/to/test1D and /path/to/test2D?

declare -a DAEMONS=('test1D' 'test2D')

for i in "${DAEMONS[@]}"
do
    perl -e '$0="/path/to/'$i'"; sleep infinity' &
done
3

There are 3 answers

4
Jasper N. Brouwer On BEST ANSWER

This should do what you want:

perl -e "\$0='/path/to/$i'; sleep infinity" &

By using double-quotes as surrounding quotes, you can specify the string that should be evaluated by Perl, but keep the ability to use shell variables:

Because everything starting with $ will now be seen as a shell variable, so the shell will try to parse $0. But you want it to end up as $0 in Perl, so you'll need to escape the $ sign. That's why you see \$0 here.

We leave $i intact, so the shell will substitute it with the value of i.

So asuming the value of i is test1D, Perl will now receive:

$0='/path/to/test1D'; sleep infinity
0
Charles Duffy On

A safer alternative is to pass data through the environment, rather than substituting into code:

declare -a DAEMONS=('test1D' 'test2D')

for i in "${DAEMONS[@]}"
do
    daemon="$i" perl -e '$0="/path/to/" + $ENV{daemon}; sleep infinity' &
done
3
David W. On

Just to let you know, you don't need arrays for something like this:

daemons="test1D test2D"

for deamon in $daemons
do
    perl -e '$0="/path/to/'$daemon'"; sleep infinity' &
done

Or, even better:

set test1D test2D
for daemon in $*
do
    perl -e '$0="/path/to/'$daemon'"; sleep infinity' &
done