Bash 子 Shell

作者:Mitch Frazier

在编写 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 文件的情况下死亡等等。 但是,那是现实世界,这是示例世界。

Mitch Frazier 是 Emerson Electric Co. 的一名嵌入式系统程序员。自 2000 年代初期以来,Mitch 一直是 Linux Journal 的贡献者和朋友。

加载 Disqus 评论