为什么在后台进程结束之前函数不会返回?

为什么在后台进程结束之前函数不会返回?

考虑这个脚本:

#!/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都会显示在您的控制台中。

相关内容