如何在不获取 nohup.out 的情况下使用 nohup 命令?

Posted

技术标签:

【中文标题】如何在不获取 nohup.out 的情况下使用 nohup 命令?【英文标题】:How do I use the nohup command without getting nohup.out? 【发布时间】:2012-05-11 15:16:09 【问题描述】:

我的 nohup 命令有问题。

当我运行我的工作时,我有很多数据。输出 nohup.out 变得太大,我的进程变慢了。如何在不获取 nohup.out 的情况下运行此命令?

【问题讨论】:

unix.stackexchange.com/q/23010/2644 的副本 【参考方案1】:

nohup 命令仅在输出到终端时才写入nohup.out。如果您已将命令的输出重定向到其他地方 - 包括 /dev/null - 这就是它的位置。

 nohup command >/dev/null 2>&1   # doesn't create nohup.out

如果您使用的是nohup,这可能意味着您想在后台运行命令,方法是在整个过程的末尾加上另一个&

 nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out

在 Linux 上,使用 nohup 运行作业也会自动关闭其输入。在其他系统上,尤其是 BSD 和 macOS,情况并非如此,因此在后台运行时,您可能需要手动关闭输入。虽然关闭输入对 nohup.out 的创建没有影响,但它避免了另一个问题:如果后台进程试图从标准输入中读取任何内容,它将暂停,等待您将其带回前台并输入内容.所以额外安全的版本看起来像这样:

nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal 

但是请注意,这不会阻止命令直接访问终端,也不会将其从 shell 的进程组中删除。如果您想执行后者,并且您正在运行 bash、ksh 或 zsh,则可以通过运行 disown 来实现,并且不带任何参数作为下一个命令。这将意味着后台进程不再与外壳“作业”相关联,并且不会有任何信号从外壳转发给它。 (注意区别:disowned 进程没有收到其父 shell 自动转发给它的信号 - 但没有nohup,它仍会收到通过其他方式发送的HUP 信号,例如手动kill命令。nohup'ed 进程忽略任何和所有 HUP 信号,无论它们是如何发送的。)

解释:

在 Unixy 系统中,每个输入源或输出目标都有一个与之相关的数字,称为“文件描述符”,或简称为“fd”。每个正在运行的程序(“进程”)都有自己的一组,当一个新进程启动时,其中三个已经打开:“标准输入”,即 fd 0,是开放的,可供进程读取,而“标准输出”(fd 1)和“标准错误”(fd 2)是开放的,可以写入。如果您只是在终端窗口中运行命令,那么默认情况下,您键入的任何内容都会转到其标准输入,而其标准输出和标准错误都会发送到该窗口。

但是您可以在启动命令之前要求 shell 更改任何或所有这些文件描述符指向的位置;这就是重定向(&lt;&lt;&lt;&gt;&gt;&gt;)和管道(|)运算符所做的。

管道是其中最简单的...command1 | command2 安排command1 的标准输出直接馈送到command2 的标准输入。这是一个非常方便的安排,导致了 UNIX 工具中的特定设计模式(并解释了标准错误的存在,它允许程序向用户发送消息,即使它的输出正在进入管道中的下一个程序) .但是您只能将标准输出通过管道传输到标准输入;如果没有一些杂耍,你不能将任何其他文件描述符发送到管道。

重定向操作符更友好,因为它们允许您指定要重定向的文件描述符。所以0&lt;infile 从名为infile 的文件中读取标准输入,而2&gt;&gt;logfile 将标准错误附加到名为logfile 的文件的末尾。如果不指定数字,则输入重定向默认为 fd 0(&lt;0&lt; 相同),而输出重定向默认为 fd 1(&gt;1&gt; 相同)。

此外,您可以将文件描述符组合在一起:2&gt;&amp;1 表示“在标准输出所在的地方发送标准错误”。这意味着您将获得一个输出流,其中包括标准输出和标准错误混合在一起,无法再将它们分开,但这也意味着您可以在管道中包含标准错误。

所以序列&gt;/dev/null 2&gt;&amp;1 的意思是“将标准输出发送到/dev/null”(这是一个特殊的设备,只会丢弃您写入的任何内容)“然后将标准错误发送到标准输出的任何地方”(其中我们只是确定是/dev/null)。基本上,“丢弃此命令写入任一文件描述符的任何内容”。

nohup 检测到它的标准错误和输出都没有连接到终端时,它不会费心创建nohup.out,而是假定输出已经被重定向到用户希望它去的地方。

/dev/null 设备也可用于输入;如果您使用&lt;/dev/null 运行命令,则该命令从标准输入读取的任何尝试都会立即遇到文件结尾。请注意,合并语法在这里不会产生相同的效果;它仅适用于将文件描述符指向另一个在同一方向(输入或输出)打开的文件描述符。 Shell 将允许您执行&gt;/dev/null &lt;&amp;1,但最终会创建一个在输出流上打开输入文件描述符的进程,因此任何读取尝试都将触发致命的“无效文件描述符”,而不是仅仅命中文件结尾" 错误。

【讨论】:

关于nohup,“如果该进程稍后尝试从标准输入读取任何内容,它将暂停,等待您将其带回前台并输入内容。”似乎不正确。相反,nohupcloses standard input (the program will not be able to read any input, even if it is run in the foreground. it is not halted, but will receive an error code or EOF). @Tim - 这个答案对于 Linux 是正确的,但对于 BSD 或 OS X 不正确,nohup 在其上 not 会自动关闭标准输入。请注意,nohup 不是内置的 shell,而是二进制实用程序。 nohup 是 coreutils 的一部分。你的意思是nohup 的实现对于 linux 和 BSD 或 OS X 是不同的吗? 是的。 “coreutils”这个名字指的是一个 GNU 包。但是 BSD、OS X、SmartOS/Illumos 和许多商业 Unix(基本上,那些比 GNU 存在时间更长的 Unix)具有非 GNU 核心实用程序。 awk 不同,sed 不同,nohup 不同... 这是最好的。三种方式中的每一种都可以完美地满足每个人的需求。 THx【参考方案2】:
nohup some_command > /dev/null 2>&1&

这就是你需要做的!

【讨论】:

还有另一个答案几乎有同样的东西,但他们最后没有额外的“&”。 上面的&amp; 将使您无需使用ctrl-c,如果这对您很重要的话。 在BG中运行的能力很有帮助 这仅在您不关心捕获some_command 输出(包括错误)时才有用。【参考方案3】:

您是否尝试过重定向所有三个 I/O 流:

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &

【讨论】:

不应该是&gt; /dev/null 而不是/null? @ScottChu &lt; /dev/null 重定向nohup 的标准输入。 Linux 不需要这样做,但 POSIX 允许 nohup 在标准输入连接到终端时无法在后台运行的行为。此类系统的示例是 BSD 和 OS X。【参考方案4】:

您可能想使用detach program。您可以像 nohup 一样使用它,但除非您告诉它,否则它不会产生输出日志。这是手册页:

NAME
       detach - run a command after detaching from the terminal

SYNOPSIS
       detach [options] [--] command [args]

       Forks  a  new process, detaches is from the terminal, and executes com‐
       mand with the specified arguments.

OPTIONS
       detach recognizes a couple of options, which are discussed below.   The
       special  option -- is used to signal that the rest of the arguments are
       the command and args to be passed to it.

       -e file
              Connect file to the standard error of the command.

       -f     Run in the foreground (do not fork).

       -i file
              Connect file to the standard input of the command.

       -o file
              Connect file to the standard output of the command.

       -p file
              Write the pid of the detached process to file.

EXAMPLE
       detach xterm

       Start an xterm that will not be closed when the current shell exits.

AUTHOR
       detach was written by Robbert Haarman.  See  http://inglorion.net/  for
       contact information.

请注意,我与该程序的作者没有任何关系。我只是该程序的满意用户。

【讨论】:

链接没有损坏,并且 git repo 是旧的。它不包括当前的 v0.2.3。【参考方案5】:

下面的命令可以让你在后台运行一些东西而不会得到 nohup.out:

nohup command |tee &

通过这种方式,您将能够在远程服务器上运行脚本时获得控制台输出:

【讨论】:

【参考方案6】:
sudo bash -c "nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null"  &

重定向 sudo 的输出会导致 sudo 重新请求密码,因此需要一个笨拙的机制来执行此变体。

【讨论】:

【参考方案7】:

如果您面前的 mac/linux 上有 BASH shell,请尝试以下步骤以实际了解重定向:

创建一个名为 zz.sh 的 2 行脚本

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
echo 命令的输出进入 STDOUT 文件流(文件描述符 1)。 错误命令的输出进入 STDERR 文件流(文件描述符 2)

目前,只需执行脚本即可将 STDOUT 和 STDERR 发送到屏幕。

./zz.sh

现在从标准重定向开始:

zz.sh > zfile.txt

在上面,“echo”(STDOUT)进入 zfile.txt。而“错误”(STDERR)显示在屏幕上。

以上同:

zz.sh 1> zfile.txt

现在您可以尝试相反的方法,并将“错误”STDERR 重定向到文件中。 “echo”命令的 STDOUT 进入屏幕。

zz.sh 2> zfile.txt

结合以上两个,你得到:

zz.sh 1> zfile.txt 2>&1

解释:

首先,将 STDOUT 1 发送到 zfile.txt 然后,将 STDERR 2 发送到 STDOUT 1 本身(通过使用 &1 指针)。 因此,1 和 2 进入同一个文件 (zfile.txt)

最终,您可以将整个内容打包到 nohup command & 中以在后台运行:

nohup zz.sh 1> zfile.txt 2>&1&

【讨论】:

【参考方案8】:

您可以运行以下命令。

nohup <your command> & >  <outputfile> 2>&1 &

例如 我在脚本中有一个 nohup 命令

./Runjob.sh > sparkConcuurent.out 2>&1

【讨论】:

以上是关于如何在不获取 nohup.out 的情况下使用 nohup 命令?的主要内容,如果未能解决你的问题,请参考以下文章

sh 如何在不获取nohup.out的情况下使用nohup命令?

一次线上nohup.out日志丢失的问题

如何在不复制的情况下从 N 维容器中获取可迭代范围?

Linux下如何不停止服务,清空nohup.out文件

如何在不调用索引函数或任何内置函数的情况下获取列表中的索引?

在不调用属性的情况下获取休眠惰性关系 n+1 - Kotlin