在 Linux 中使用 bash 命令一个接一个的运行脚本
1. 概述
在本教程中,我们将学习在 Linux 中如何在另一个 bash 脚本完成后启动它。如果我们想一个接一个地排队作业,这会很有用。
2. 在同一个 Shell 中启动另一个脚本
如果脚本在当前 shell 中运行,我们可以很容易地在它之后启动另一个。
对于本教程,我们将使用分别位于*/home/blogdemo/script1.sh和/home/blogdemo/script2.sh*的两个示例脚本。他们只是睡了一段时间并打印了一条消息:
$ cat ./script1.sh
echo "Sleeping for 60 seconds..."
sleep 60
echo "Slept for 60 seconds"
$ cat ./script2.sh
echo "Sleeping for 45 seconds..."
sleep 45
echo "Slept for 45 seconds"
2.1. 使用 && 运算符
**bash &&运算符在第一个命令退出后执行另一个命令。**它的用法语法是command1 && command2 && …:
$ ./script1.sh && ./script2.sh
Sleeping for 60 seconds...
Slept for 60 seconds
Sleeping for 45 seconds...
Slept for 45 seconds
我们应该注意到&&运算符仅在第一个命令返回退出代码 0 时才执行第二个命令。
如果我们想运行下一个脚本,即使第一个脚本失败了,我们也可以用 ; 替换*&&*运算符。运算符,无论退出代码如何,它都会运行下一个命令。
2.2. 使用wait
我们可以先在后台启动一个脚本,然后等待它完成,然后再使用wait 命令执行另一个脚本。
我们使用单个*&*运算符来启动后台进程:
$ ./script1.sh &
$ Sleeping for 60 seconds...
$ wait && ./script2.sh
Slept for 60 seconds
Sleeping for 45 seconds...
Slept for 45 seconds
[1]+ Done ./script1.sh
即使进程以非零故障代码退出,此命令也有效。
此外,我们可以使用Ctrl + C组合键取消wait命令:
$ ./script1.sh &
$ Sleeping for 60 seconds...
$ wait && ./script2.sh # Cancel wait
^C
$ wait && ./script2.sh # Restart wait
Slept for 60 seconds
Sleeping for 45 seconds...
Slept for 45 seconds
[1]+ Done ./script1.sh
这种方法允许我们在同一个 shell 中做其他工作,但是我们必须再次键入wait && command2以防我们想再次等待进程完成。
2.3. 使用fg
如果命令已经在后台运行,我们可以使用fg 命令将其调到前台:
$ ./script1.sh &
Sleeping for 60 seconds...
$ fg; ./script2.sh
./script1.sh
Slept for 60 seconds
Sleeping for 45 seconds...
Slept for 45 seconds
如果它已经是前台进程,那么我们可以使用Ctrl + Z组合键暂停它,然后使用fg运行下一个脚本:
$ ./script1.sh
Sleeping for 60 seconds...
^Z[1]+ Stopped ./script1.sh
$ # We suspended the process, now we can use fg.
$ fg; ./script2.sh
./script1.sh
Slept for 60 seconds
Sleeping for 45 seconds...
Slept for 45 seconds
fg阻塞直到命令完成,因此我们可以使用; 运算符运行下一个脚本。**
我们应该注意fg不能像wait一样取消和恢复,因为fg将脚本的控制权交还给我们而不是等待脚本完成。所以所有的动作都适用于脚本本身。
3. 在 Shell 之外启动另一个脚本
有时我们可能无法访问启动脚本的原始 shell。当我们从另一个 shell守护脚本 然后关闭终端时,通常会发生这种情况。在这种情况下,我们可以定期轮询脚本的进程 ID,并在进程 ID 不再存在时启动另一个脚本。
我们可以使用pgrep 通过传入脚本名称作为参数来查找脚本的进程 ID:
$ pgrep script1
7775
现在,我们可以定期检查这个进程 ID 是否已完成执行,然后运行我们的脚本:
pid=7775
# An entry in /proc means that the process is still running.
while [ -d "/proc/$pid" ]; do
sleep 1
done
./script2.sh
我们应该注意,此方法不会在第一个完成后立即运行脚本,因为我们会在再次轮询之前休眠 1 秒。如果需要更高的精度,我们可以将睡眠减少到较低的数量,例如100 毫秒sleep 0.1。