Nohup在后台关闭终端结束进程运行时不起作用?

Nohup take no effect when to close the terminal end the process running in background?

nohup command &可以在关闭终端后保留命令运行ning。 我想播放目录 Music.

中的所有 mp3 音乐
ls Music/*mp3 |xargs -d "\n" mplayer  

ls Music/*mp3可以列出目录Music下的所有mp3文件,用xargs通过管道发送,-d "\n"是处理文件名中的空格。

我想将所有 stdoutstderr 重定向到 /dev/null,并在后台将其 运行 重定向。

ls Music/*mp3 |xargs -d "\n" mplayer > /dev/null 2>&1 &

这很好用,但我希望在关闭终端后 运行ning。

nohup ls Music/*mp3 | xargs -d "\n" mplayer > /dev/null 2>&1 &
ls Music/*mp3 | xargs -d "\n" nohup mplayer > /dev/null 2>&1 &
ls Music/*mp3 | nohup xargs -d "\n" mplayer > /dev/null 2>&1 &

当我关闭终端时,后台进程运行ning结束。
为什么nohup在以上三个命令中都不生效?我怎样才能让它生效?

disown 可以解决问题,但我想要一个使用 nohup.

的解决方案
ls Music/*mp3 | xargs -d "\n" mplayer > /dev/null 2>&1 & disown

nohup 不适用于管道。使用以下方式:

nohup sh -c 'ls  Music/*mp3 |  xargs  -d  "\n"  mplayer' &

nohup command means "run command and ignore HUP signals".

所以在我们能够有效地使用nohup之前我们需要问:SIGHUP是什么时候以及如何发送的?正如 Bash 手册所说,"Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped."。它继续说抑制这种行为的正确方法是使用 disown。我知道你问的是 nohup,但值得一提的是 disown 是完成你想要的目标的预期且更简单的方法。请注意 disown 而不是 等同于 nohup.

nohup 在此处难以使用的原因是因为它适用于单个进程,而 & 创建一个背景 job of a whole command pipeline,它可以由多个进程组成。这意味着您需要 nohup 管道中的每个命令,以确保各个命令不会收到 SIGHUP,例如:

$ nohup ls Music/*mp3 2>/dev/null | nohup xargs -d "\n" nohup mplayer &> /dev/null &

这个 应该 可以工作,尽管我还没有使用这些特定命令对其进行测试。如果没有,则可能是您没有直接启动的另一个进程仍在接收 SIGHUP。这很难解决,这正是我们有 disown.

的原因

manishg的建议也有道理;通过将管道移动到一个单独的进程中,您可以 nohup that 进程,这反过来会阻止 SIGHUP 在 shell 关闭时到达其子进程。


综上所述,您一开始就不需要 lsxargsfind 可用于类似的效果,并将简化有关命令的推理。尝试:

$ nohup find Music -maxdepth 1 -name '*mp3' -exec mplayer {} + &> /dev/null &

I want to play all mp3 music in directory Music.

通常,您不需要 lsxargs
您可以将整个管道简化为 mplayer Music/*mp3 ✱.
这不仅对特殊文件名更安全,而且还解决了 nohup:

的问题
nohup mplayer Music/*mp3 &> /dev/null &
✱ 只有一种情况下此命令会失败并且 `ls * | xargs 成功。如果您有大量的 mp3 文件,您可能 运行 进入命令行长度限制。以字节为单位的限制由 `getconf ARG_MAX` 给出。在我的系统上它是 2097152,这意味着假设最大文件名长度为 255 字节,您至少需要 8000 个文件。使用较短的文件名,您可以拥有更多的文件。例如,如果您的 mp3 文件通常长约 40 个字节,则您可以使用超过 44000 个文件。

有两种关闭终端的方法。
exit方式:

在终端输入exit然后点击enter

cross方式:
点击右上角的cross

用相同的png文件来说明它们。 nohup 只能通过 exit 方式对以下所有命令生效(在终端中至少检查了每个人三遍)。

ls Music/*mp3 |xargs -d "\n" nohup mplayer  > /dev/null 2>&1 &
ls  Music/*mp3 | nohup  xargs  -d  "\n"  mplayer  > /dev/null  2>&1  &
nohup ls Music/*mp3 2>/dev/null | nohup xargs -d "\n" nohup mplayer &> /dev/null &
nohup find Music -maxdepth 1 -exec mplayer {} \; &> /dev/null &
nohup mplayer Music/*mp3 &> /dev/null &

nohup sh -c nohup bash -c 的一个小错误:

nohup sh -c 'ls  Music/*mp3 |  xargs  -d  "\n"  mplayer' &
[1] 4581
nohup: ignoring input and appending output to 'nohup.out'
nohup bash -c 'ls  Music/*mp3 |  xargs  -d  "\n"  mplayer' &
[1] 16831
nohup: ignoring input and appending output to 'nohup.out'

当以cross方式关闭终端时,以上所有命令都不会在后台播放音乐。

disown结尾的命令将继续以任何方式(exitcross方式)在后台播放音乐。
关闭终端后最好执行 disown 命令,以便继续在后台播放音乐。