如何编写 bash 脚本,当且仅当前一个命令的处理完成时才触发下一个命令

如何编写 bash 脚本,当且仅当前一个命令的处理完成时才触发下一个命令

我有这样的命令,它将触发一个进程

./extract.sh 1553212800 1554854400 & 

例如,这将给出一个进程 ID1234

我只想在1234完成后运行下一个命令

./extract.sh 1554854400 1556668800 & 

类似这样的命令还有很多

答案1

如果您想等待它完成,似乎没有必要将其放在后台,但是:

./extract.sh 1553212800 1554854400 & 
pid=$!
if wait "$pid"; then
    ./extract.sh 1554854400 1556668800 & 
fi

内置程序wait退出时显示:

返回最后一个ID的状态;如果 ID 无效或给出的选项无效,则失败。

答案2

你可以删除&每个命令末尾的 ,这样 shell 就会运行这些命令不是作为后台任务,或者,如果您确实需要将它们作为后台任务运行(因为您还并行执行其他操作),则需要将进程的 PID 保存在变量中,然后wait才能完成:

./extract.sh 1553212800 1554854400 & pid="$!"

# other things

wait "$pid"

./extract.sh 1554854400 1556668800 &  & pid="$!"

# other things (again)

wait "$pid"

# etc.

就我个人而言,如果我有一长串此类命令,我会将它们全部放在一个脚本中,例如

#!/bin/sh

./extract.sh 1553212800 1554854400
./extract.sh 1554854400 1556668800

(注意,没有后台作业)

然后我可能会这样开始脚本nohup

nohup ./script.sh &

这将允许我注销然后重新登录以查看脚本进程是否仍在运行(通过使用检查ps)。

或者,我只需启动一个tmux会话,然后像平常一样启动脚本(否nohup),然后按Ctrl+Bd与之分离。稍后,我可以使用 . 回到相同的 shell 会话tmux attach。请参阅tmux手册。

答案3

虽然这可能无法直接回答所述问题,但我想我会提出这个解决方案,特别是因为 OP 看起来还没有确定管道。

在许多 Posix shell 中,可以通过符号将多个命令链接在一起&&。基本上,这意味着运行第一个命令,然后在第一个命令运行完成且没有错误后,运行&&.例如:

./extract.sh 1553212800 1554854400 && ./extract.sh 1554854400 1556668800 &

但是,这会将所有内容作为单个大型后台进程运行。此外,您还面临着永远不会运行引发错误的命令后面的命令的风险。所以在这样的场景中:

./valid_run.sh && ./throws_error.sh && ./second_valid_run.sh

如果valid_run.sh运行正常,但throws_error.sh不运行,则second_valid_run.sh不会运行。

或者,一种更简洁的方法是将所有命令保存在包装器 BASH 脚本中,然后运行该脚本:

包装器.sh:

#!/bin/bash
./extract.sh 1553212800 1554854400
./extract.sh 1554854400 1556668800

命令行:

$ ./wrapper.sh &

我认为这可能是组织命令的最佳方式。

相关内容