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

use*_*565 21 bash shell-script command-substitution background-process

考虑这个脚本:

#!/bin/bash
function start {
  leafpad &
  echo $!
}
PID=$(start)
echo "PID is $PID"
Run Code Online (Sandbox Code Playgroud)

即使是后台进程,该脚本也不会继续越过其右大括号直到 Leafpad 进程结束。

为什么是这样?是否可以从函数启动后台进程?

Adr*_* M. 22

该函数返回,但命令替换阻止,因为您创建了一个后台作业,但您仍然打开了 stdout fd。只需>/dev/null&.

#!/bin/bash
function start {
  leafpad >/dev/null &
  echo $!
}
PID=$(start)
echo "PID is $PID"
Run Code Online (Sandbox Code Playgroud)

如果您希望您的进程也关闭 stdin、stdout、stderr,请使用以下命令:

leafpad >/dev/null 0>&1 2>&1 &
Run Code Online (Sandbox Code Playgroud)

这将关闭标准输入 (0)、标准输出 (1) 和标准错误 (2),然后关闭背景 (&)。此外,在使用这些流重定向时不要忘记它们是“被欺骗的”,这意味着按照执行顺序重复。

1>/dev/null 2>&1
Run Code Online (Sandbox Code Playgroud)

2>&1 1>/dev/null
Run Code Online (Sandbox Code Playgroud)

不一样!在前者中,您将流复制到 /dev/null(这是您想要的),在后者中,您将 /dev/stdout 复制到 stderr,然后关闭 stdout。因此,发送到的任何消息stderr都会出现在您的控制台中。

  • 您不是关闭流,而是重定向它们。 (10认同)
  • 关闭;`n>&-` 其中 `n` 是文件描述符。 (4认同)