考虑这个脚本:
#!/bin/bash
function start {
leafpad &
echo $!
}
PID=$(start)
echo "PID is $PID"
在 leafpad 进程结束之前,该脚本不会继续越过其右大括号,即使它是一个后台进程。
为什么是这样?是否可以从函数启动后台进程?
答案1
该函数返回,但命令替换会阻塞,因为您创建了一个后台作业,但您的 stdout fd 仍然打开。只需>/dev/null
在 之前添加即可将其关闭&
。
#!/bin/bash
function start {
leafpad >/dev/null &
echo $!
}
PID=$(start)
echo "PID is $PID"
如果您希望进程也关闭 stdin、stdout、stderr,请使用以下命令:
leafpad >/dev/null 0>&1 2>&1 &
这将关闭 stdin (0)、stdout (1) 和 stderr (2),然后关闭背景 (&)。另外,当使用这些流重定向不要忘记它们是“被欺骗的”,这意味着在执行顺序上是重复的。
1>/dev/null 2>&1
和
2>&1 1>/dev/null
不一样!在前者中,您将流复制到 /dev/null (这就是您想要的),在后者中,您将 /dev/stdout 复制到 stderr,然后关闭 stdout。因此,发送到的任何消息stderr
都会显示在您的控制台中。