如何使用nohup命令而不输出nohup.out?

回答 8 浏览 46万 2012-05-02

我在使用nohup命令时遇到了一个问题。

当我运行我的工作时,我有大量的数据。输出 nohup.out 变得太大,我的进程变慢了。我怎样才能在运行这个命令时不出现nohup.out?

Ofer 提问于2012-05-02
8 个回答
#1楼 已采纳
得票数 805

nohup 命令只在输出会到终端的情况下写到nohup.out。如果你把命令的输出重定向到其他地方--包括/dev/null--那就是它要去的地方。

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

请注意,>/dev/null 2>&1 序列在大多数(但不是全部)shell 中可以缩写为 >&/dev/null

如果你使用的是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,不加任何参数作为下一个命令来实现。这将意味着后台进程不再与shell的"job"相关联,并且不会有任何信号从shell转发给它。(一个disown的进程不会被它的父级shell自动转发任何信号--但是如果没有nohup,它仍然会收到通过其他方式发送的HUP信号,例如一个手动的kill命令。一个nohup'ed进程会忽略任何和所有的HUP信号,无论它们是如何被发送的。)

解释一下。

在Unixy系统中,每个输入源或输出目标都有一个与之相关的编号,称为"文件描述符",或简称为"fd"。每个正在运行的程序("进程")都有自己的一组描述符,当一个新进程启动时,它已经打开了其中的三个描述符:"标准输入",即fd0,是为进程读取而打开的,而"标准输出"(fd1)和"标准错误"(fd2)是为它写的。如果你只是在一个终端窗口中运行一个命令,那么默认情况下,你输入的任何东西都会进入其标准输入,而其标准输出和标准错误都会发送到该窗口。

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

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

重定向操作符更友好,因为它们让你指定重定向哪个文件描述符。因此,0<infile从名为infile的文件中读取标准输入,而2>>logfile将标准错误附加到名为logfile的文件末尾。如果你不指定数字,那么输入重定向默认为fd 0(<0<相同),而输出重定向默认为fd 1(>1>相同).

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

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

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

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

Mark Reed 提问于2012-05-02
Mark Reed 修改于2022-09-22
关于nohup,“如果该进程稍后尝试从标准输入中读取任何内容,它将暂停,等待您将其带回前台并输入内容。”似乎不正确。相反,nohup 关闭标准输入(程序将无法读取任何输入,即使它在前台运行. 它不会停止,但会收到错误代码或 EOF)。Tim 2016-03-01
@Tim - 这个答案对Linux来说是正确的,但对BSD或OS X来说是不正确的,在它们身上,nohup不会自动关闭标准输入。请注意,nohup不是一个shell内置程序,而是一个二进制工具。Mark Reed 2016-03-01
nohup是coreutils的一部分。你的意思是nohup的实现在linux和BSD或OS X中是不同的吗?Tim 2016-03-01
是的,"coreutils "这个名字指的是一个GNU软件包。但BSD、OS X、SmartOS/Illumos和许多商业Unix--基本上,那些比GNU历史更悠久的Unix--都有非GNU的核心工具。awk是不同的,sed是不同的,nohup是不同的...。Mark Reed 2016-03-01
这是最好的。3种方式都能满足各自的需要,完美地诠释了这一点。THxKangarooo 2017-07-15
#2楼
得票数 86
nohup some_command > /dev/null 2>&1&

这就是你所需要做的一切!

这就是你所需要做的一切。

11101101b 提问于2012-05-22
还有一个答案几乎也是这样的,但他们没有在结尾处多加一个"&"。11101101b 2012-05-22
上的&将使你不需要使用ctrl-c,如果这对你来说很重要的话。SunSparc 2013-05-29
在BG中运行的能力是非常有帮助的ist_lion 2015-07-15
这只有在你对捕捉some_command输出(包括错误)不感兴趣的情况下才有用。wulfgarpro 2017-05-10
#3楼
得票数 15

你是否尝试过重定向所有三个I/O数据流。

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &
Aziz Shaikh 提问于2012-05-02
不应该是> /dev/null,而不是< /dev/null?Scott Chu 2016-11-24
@ScottChu < /dev/nullnohup重定向了标准输入。Linux并不要求这样做,但POSIX允许这样的行为:如果nohup的标准输入连接到终端,它就不能在后台运行。这种系统的例子是BSD和OS X。Mikko Rantalainen 2018-01-25
#4楼
得票数 11

你可能想使用detach程序。你可以像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.

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

Dan D. 提问于2012-05-02
该链接没有中断,而且该git repo是旧的。它不包括当前的v0.2.3。Dan D. 2014-03-20
#5楼
得票数 6

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

nohup command |tee &

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

Clownfish 提问于2018-03-14
Clownfish 修改于2018-03-14
#6楼
得票数 4
sudo bash -c "nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null"  &

重定向sudo的输出会导致sudo重新询问密码,因此需要一个笨拙的机制来做这个变体。

Kjeld Flarup 提问于2015-03-12
samayo 修改于2016-04-21
#7楼
得票数 4

如果你在你的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。而 "error"(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命令&中,以便在后台运行它。

nohup zz.sh 1> zfile.txt 2>&1&
Thyag 提问于2018-09-28
Thyag 修改于2018-09-28
#8楼
得票数 1

你可以运行下面的命令。

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

例如,我在脚本里有一个nohup命令。

./Runjob.sh > sparkConcuurent.out 2>&1
Prem S 提问于2017-03-17
Keet Sugathadasa 修改于2020-02-03
标签