0

我写了一个脚本After.sh来推迟一个工作在另一个正在运行的工作完成后开始:

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."

我运行它就像After.sh 5327 shutdown 0在 PID=5327 的作业完成后关闭 PC。即使我可以运行它After.sh "5327 5778 5935" shutdown 0,这样它会等到所有作业 5327 5778 和 5935 首先完成。

我的问题是当我想将更复杂的工作作为脚本的参数提供时,例如:

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

现在它运行时出现错误:for: command not found. 我试图将${*:2}脚本中的命令替换为sh ${*:2}or eval ${*:2},但它们失败了(sh再次找不到for命令,eval保留整个循环的第一个值$f,因此每次都打印第一个文件的名称。)

你知道如何解决它吗?

4

1 回答 1

2

问题是,您for f in *; do echo $f; done不是命令,而是bash -code,需要执行 bash-interpreter。

您可以使用以下命令启动解释器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."

然后对命令使用单引号,包括应通过以下方式评估的变量After

./After.sh 123 'for f in *; do echo $f; done'
于 2013-08-05T13:23:38.083 回答