使用 nohup 将标准输出重定向到文件不起作用

Mic*_*rer 2 nohup background-process stdout stderr

我正在尝试在后台运行 C 程序。我还想保存程序的标准输出。

但是,如果我尝试以下操作,nohup 只会将 stderr 输出重定向到 logfile.txt:

nohup ./GetTempValues 11 4 > logfile.txt 2>&1 &
Run Code Online (Sandbox Code Playgroud)

其中 11 和 4 是我需要传递给我的程序的参数,最后一个&是在后台运行程序(GetTempValues 是我的程序)。

Gui*_*ido 8

您确定GetTempValues开始时会产生任何标准输出吗?因为你的语法“对我有用”:

$ nohup perl test.pl >logfile.txt 2>&1 &
[1] 20964
$ cat logfile.txt 
this goes to stderr
this goes to stdout
[1]+  Done                    nohup perl test.pl > logfile.txt 2>&1
Run Code Online (Sandbox Code Playgroud)

这里test.pl

print STDOUT "this goes to stdout\n";
print STDERR "this goes to stderr\n";
Run Code Online (Sandbox Code Playgroud)

PS:在您的示例中,2>&1不需要将 STDERR 重定向到 STDOUT nohup,因为“如果标准错误是终端,则它被定向到与标准输出相同的位置。” nohup手册页)。


Jam*_*den 5

正如 Guido 上面指出的那样,nohup已经为您重定向了标准错误,除非您将其重定向到文件。dup2(2)如果您使用的是 Linux,那么在 nohup 下运行一个简单的命令并查看之前的调用可能会很有帮助execve(2)

\n\n

我怀疑你所看到的就是你认为所看到的。让我们想想当你说时会发生什么

\n\n
nohup foo 2>&1\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. shell 将 stderr 重定向到 stdout。
  2. \n
  3. 然后它调用nohup,它继承了这种情况(stderr 和 stdout 使用相同的文件描述符)。
  4. \n
  5. nohup打开nohup.out(文件描述符 3),将其复制到文件描述符 1,然后关闭 3。
  6. \n
  7. nohup注意到 stderr 不是文件,并且也复制文件描述符 1 到 2。因此文件描述符 1 和 2 都引用nohup.out.
  8. \n
  9. nohupexec使用命令行上提供的任何参数进行调用(在本例中为foo)。新进程继承nohup为其设置的 文件描述符。
  10. \n
\n\n

从命令行中,您无法创建如您所说的nohup 仅重定向 stderr-outputs 的情况。 nohup总是将 stdout 和 stderr 写入文件。stdout 要么转到您通过重定向指定的一个,要么转到nohup.out; stderr 遵循 stdout,除非您明确将其重定向到另一个文件。

\n\n

2>&1使用nohup的一个特殊方面是 GNU 版本在 stderr nohup 上生成一条毫无意义的消息:忽略输入并将输出附加到 \xe2\x80\x98nohup.out\xe2\x80\x99。(还有什么其他实用程序会向标准错误写入一条消息,相当于说,按照文档的说明进行操作?)通常,该噪音会写入终端;在重定向下,它最终成为输出文件的第一行。

\n