0

I have a command which I run via eval as shown below.

#! /bin/sh

readonly scr="MYENV=1 sh /tmp/scr.sh"

eval ${scr} -a 1 -b 2

Now I want to run the scr script with lockf utility, so I made the following changes:

#! /bin/sh

readonly scr="MYENV=1 sh /tmp/scr.sh"

lockf -k /tmp/f.lock eval ${scr} -a 1 -b 2

This throws the following error:

lockf: eval: No such file or directory

Basically the limitation is the MYENV=1 which needs to be exported while running the command (thus the use of eval).

I'm a beginner in shell programming and am unsure on how to get around this. How do I make this work?

2 Answers 2

1

eval is a shell builtin. In general using it is discouraged as it is easy to get things wrong.

You probably just need

#!/bin/sh
MYENV=1 lockf -k /tmp/f.lock sh /tmp/scr.sh -a 1 -b 2
1
readonly scr="MYENV=1 sh /tmp/scr.sh"
eval ${scr} -a 1 -b 2

Here, you'd probably be better off with a function:

scr() {
    MYENV=1 sh /tmp/scr.sh "$@"
}
scr -a 1 -b 2

That still doesn't help with running it through lockf, unless you do something like export the function (in Bash), and then have lockf run a shell, so that the function is available.

You could avoid having the awkward assignment word there by using env to set the variable. It's an external program, so available for lockf too. With the way you store the command earlier:

readonly scr="env MYENV=1 sh /tmp/scr.sh"
$scr -a 1 -b 2
# or 
lockf -k /tmp/f.lock $scr -a 1 -b 2

But note that that's not a good way to store a command, it'll fail the moment you need to store e.g. a filename with spaces in there. A better way would be to use an array (in Bash/ksh/zsh):

scr=(env MYENV=1 sh /tmp/scr.sh)
"${scr[@]}" -a 1 -b 2
# or 
lockf -k /tmp/f.lock "${scr[@]}" -a 1 -b 2

See: How can we run a command stored in a variable?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .