Bash 子 Shell
发布于 2008 年 11 月 11 日
在编写 bash 脚本时,您有时需要在后台运行命令。这很容易实现,只需在要后台运行的命令行末尾添加一个 & 符号即可。但是,如果您需要在后台运行多个命令,该怎么办?您可以将它们全部放入一个单独的脚本文件中,然后执行该脚本,并在后面加上 & 符号,或者您可以将命令保留在主脚本中,并将其作为子 shell 运行。
在 bash 中创建子 shell 很简单:只需将要在子 shell 中运行的命令放在括号内即可。这将导致 bash 将命令作为单独的进程启动。这组命令本质上就像一个单独的脚本文件,它们的输入/输出可以被集体重定向,并且/或者可以通过在结束括号后加上 & 符号来在后台执行它们。
作为一个有些牵强的例子,假设我们想要启动一个“服务器”,然后在它运行后,我们想要在后台监视它,以确保它仍在运行。我们假设服务器本身会成为一个守护进程,并创建一个 PID 文件,我们可以用它来监视它。当 PID 文件消失时,我们假设服务器已退出,并向某人发送电子邮件。
现在,您可以从主脚本启动服务器,然后创建一个执行监视的第二个脚本,然后从主脚本在后台执行它,但您可以从同一个脚本完成所有操作
#!/bin/bash
server_cmd=server
pid_file=$(basename $server_cmd .sh).pid
log_file=$(basename $server_cmd .sh).log
(
echo "Starting server"
echo "Doing some init work"
$server_cmd # server becomes a daemon
while true
do
if [[ -f $pid_file ]]; then
sleep 15
else
break
fi
done
mail -s "Server exitted" joe@blow.com <<<CRAP
) 2>&1 >> $log_file &
echo "Server started"
使用这个简单的例子,您当然可以直接在后台执行整个脚本,而无需使用子 shell 部分,但如果脚本是较大脚本的一部分,这可能不起作用。 同样,不需要用户记住在后台启动脚本,更不用说记住将其输出重定向到日志文件了,这也很棒。 当然,现实世界的脚本应该做很多其他事情:在启动服务器之前检查服务器是否已经在运行,如果 PID 文件已过时则删除它,检查服务器是否在没有删除其 PID 文件的情况下死亡等等。 但是,那是现实世界,这是示例世界。