>> sleep 5 & [1] 21763 >>> #hit enter [1]+ Done -6ren">
gpt4 book ai didi

bash - 在后台执行进程,不打印 "Done",并获取 PID

转载 作者:行者123 更新时间:2023-11-29 08:56:18 25 4
gpt4 key购买 nike

这似乎是一件非常微不足道的事情,但我很困惑。

要在后台执行某些操作,请使用 &:

>>> sleep 5 &
[1] 21763
>>> #hit enter
[1]+ Done sleep 5

但是使用 bashrc 源后台脚本输出作业信息非常令人沮丧,所以你可以做 this修复它:

>>> (sleep 5 &)

好的,所以现在我想获取 sleep 的 PID 以进行 waitkill。不幸的是,它在子 shell 中运行,所以典型的 $! 方法不起作用:

>>> echo $!
21763
>>> (sleep 5 &)
>>> echo $!
21763 #hasn't changed

所以我想,也许我可以让子 shell 以这种方式打印它的 PID:

>>> sleep 5 & echo $!
[1] 21803 #annoying job-start message (stderr)
21803 #from the echo

但是现在,当我将其放入子 shell 时,无论我如何 try catch 子 shell 的标准输出,它似乎都会阻塞,直到 sleep 完成。

>>> pid=$(sleep 5 & echo $!)

我如何在后台运行某些东西,获取它的 PID 并阻止它打印作业信息和“Done”?

最佳答案

解决方案A

当调用进程时,将 shell 的 stderr 重定向到该调用实例的 >/dev/null。我们可以通过复制 fd 2 来做到这一点,这样我们仍然可以将复制的 fd 用于该过程。我们在一个 block 中执行所有这些操作以临时进行重定向:

{ sleep 5 2>&3 & pid=$!; } 3>&2 2>/dev/null

现在为了防止稍后显示“完成”消息,我们从作业表中排除该进程,这是通过 disown 命令完成的:

{ sleep 5 2>&3 & disown; pid=$!; } 3>&2 2>/dev/null

如果未启用作业控制,则不需要。可以使用 set +mshopt -u -o monitor 禁用作业控制。

方案B

我们还可以使用命令替换来调用进程。我们遇到的唯一问题是进程仍然将自身 Hook 到由读取标准输出的 $() 创建的管道,但我们可以通过在它之前复制原始标准输出然后使用该进程的文件描述符来解决这个问题:

{ pid=$( sleep 200s >&3 & echo $! ); } 3>&1

如果我们将进程的输出重定向到/dev/null这样的地方,则可能没有必要:

pid=$( sleep 200s >/dev/null & echo $! )

与流程替换类似:

{ read pid < <(sleep 200s >&3 & echo $!); } 3>&1

有些人可能会说 process substitution 不需要重定向,但问题是可能正在访问其 stdout 的进程会很快死掉。例如:

$ function x { for A in {1..100}; do echo "$A"; sleep 1s; done }
$ read pid < <(x & echo $!)
$ kill -s 0 "$pid" &>/dev/null && echo "Process active." || echo "Process died."
Process died.
$ read pid < <(x > /dev/null & echo $!)
$ kill -s 0 "$pid" &>/dev/null && echo "Process active." || echo "Process died."
Process active.
  • 可选地,您可以使用 exec 3>&1 创建一个永久重复的 fd,这样您就可以在 pid=$( sleep 200s >&3 & echo $! ) 上下一行。

关于bash - 在后台执行进程,不打印 "Done",并获取 PID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24843614/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com