Domanda

I have written an script After.sh to postpone one job to be started after another running job is finished:

echo "Waiting job $1 to be finished..."
while ps -p $1 >/dev/null; do sleep 1; done ;
echo "Job $1 finished."
echo "Now running job ${*:2}..."
${*:2}
echo "Job ${*:2} finished."

I run it like After.sh 5327 shutdown 0 to shutdown the PC after the job with PID=5327 is finished. Even I can run it like After.sh "5327 5778 5935" shutdown 0, this way it waits until all jobs 5327 5778 and 5935 are finished first.

My problem is when I want to feed a more complex job as argument to the script, for instance:

After.sh 5327 for f in *; do echo $f; done

Now it runs with an error: for: command not found. I tried to replace the command ${*:2} in the script to sh ${*:2} or eval ${*:2}, but they failed (sh fails again to find for command, eval keeps the first value of $f for the whole loop, so prints the name of the first file every time.)

Do you have any idea how to fix it?

È stato utile?

Soluzione

the problem is, that you are for f in *; do echo $f; done is not a command, but rather it is bash-code, which needs a bash-interpreter to be executed.

you can start an interpreter by using eval:

#!/bin/sh

PID="$1"
shift
JOB="$@"

echo "Waiting job ${PID} to be finished..."
while ps -p ${PID} >/dev/null; do sleep 1; done ;
echo "Job ${PID} finished."
echo "Now running job '${JOB}'"
eval ${JOB}
echo "Job '${JOB}' finished."

then use single quotes for commands including variables that should be evaluated by After:

./After.sh 123 'for f in *; do echo $f; done'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top