【问题标题】:Scheduling Jobs one after other in Linux在 Linux 中一个接一个地调度作业
【发布时间】:2013-08-05 13:11:09
【问题描述】:

我写了一个脚本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}eval ${*:2},但它们失败了(sh 再次找不到for 命令,eval 保留$f 的第一个值作为整个循环,所以每次都打印第一个文件的名称。)

你知道如何解决它吗?

【问题讨论】:

  • 将复杂命令保存到文件,使其可执行,将路径作为参数提供给 After.sh。
  • @choroba 谢谢,我知道这一点,但我希望我的脚本足够灵活,可以及时处理一些 shell 命令,因为每次我都需要不同的命令
  • 您将不得不深入研究引用和反斜杠。你不能改用wait吗?
  • @choroba 你认为wait 对我来说是一个更简单的解决方案吗?
  • wait PID ; for f in * ; do echo $f; done 有效。不过,它不需要多个参数。

标签: linux bash shell job-scheduling


【解决方案1】:

问题是,你是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'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-13
    • 2020-07-17
    • 2021-09-16
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    相关资源
    最近更新 更多