是否有官方的 POSIX、GNU 或其他指南来说明应该在何处打印进度报告和日志信息(例如“Doing foo; foo done”)?就个人而言,我倾向于将它们写入 stderr,这样我就可以重定向 stdout 并仅获取程序的实际输出。我最近被告知这不是一个好的做法,因为进度报告实际上并不是错误,只有错误消息应该打印到 stderr。
这两个职位都有意义,当然您可以根据您正在做的事情的细节选择一个或另一个,但我想知道是否有一个普遍接受的标准。我无法在 POSIX、GNU 编码标准或任何其他此类广泛接受的最佳实践列表中找到任何特定规则。
我们有一些类似的问题,但它们没有解决这个确切的问题:
何时在 shell 脚本中使用重定向到 stderr:接受的答案表明我倾向于做什么,将程序的最终输出保留在 stdout 上,并将其他任何内容保留在 stderr 上。然而,这只是作为用户的意见提出的,尽管有论据支持。
使用消息应该转到 stderr 还是 stdout?:这是特定于帮助消息的,但引用了 GNU 编码标准。这就是我正在寻找的东西,不仅限于帮助消息。
那么,对于进度报告和其他信息性消息(不是程序实际输出的一部分)应该在哪里打印,是否有任何官方规则?
我想设置我的终端,以便stderr以不同的颜色打印stdout;也许是红色的。这样更容易区分两者。
有没有办法在中配置它.bashrc?如果没有,这甚至可能吗?
注意:这个问题是合并另一个是问stderr,stdout 和用户输入回波是在输出3种不同颜色。答案可能正在解决任何一个问题。
考虑以下(有点傻)脚本名称“test1.sh”:
#/bin/bash
#
sleep 10 &
echo sleep pid = $!
pkill sleep
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我不仅得到了 echo 的输出,还得到了 bash 在 stderr 上报告睡眠死亡的报告:
$ ./test1.sh
sleep pid = 3551
./test1.sh: line 5: 3551 Terminated sleep 10
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想抑制打印输出到 stderr。我知道我可以在命令行上完成,如下所示:
$ ./test1.sh 2> /dev/null
Run Code Online (Sandbox Code Playgroud)
......但有没有办法从抑制其内的脚本?(我知道我可以将它包装在第二个脚本中并让包装器重定向它,但一定有更简单的东西......)
似乎终端中的每个应用程序都会发出警告和错误消息,即使它看起来运行良好。
埃马克:
** (emacs:5004): WARNING **: Couldn't connect to accessibility bus:
Failed to connect to socket /tmp/dbus-xxfluS2Izg: Connection refused
Run Code Online (Sandbox Code Playgroud)
表明:
** (evince:5052): WARNING **: Couldn't connect to accessibility bus:
Failed to connect to socket /tmp/dbus-xxfluS2Izg: Connection refused
(evince:4985): Gtk-CRITICAL **: gtk_widget_show: assertion
'GTK_IS_WIDGET (widget)' failed
(evince:4985): Gtk-CRITICAL **: gtk_widget_show: assertion
'GTK_IS_WIDGET (widget)' failed
Run Code Online (Sandbox Code Playgroud)
火狐:
(process:5059): GLib-CRITICAL **: g_slice_set_config: assertion
'sys_page_size == 0' failed
Run Code Online (Sandbox Code Playgroud)
名单还在继续。这种行为是常见的还是我的系统有问题?我如何解决这些问题?
我怎样才能达到
cmd >> file1 2>&1 1>>file2
Run Code Online (Sandbox Code Playgroud)
也就是说,stdout和stderr 应该重定向到一个文件吗?(file1) 而只有 stdout?(file2) 应该重定向到另一个(都在附加模式下)?
我从空目录开始。
$ touch aFile
$ ls
aFile
Run Code Online (Sandbox Code Playgroud)
然后我有ls两个参数,其中一个不在此目录中。我将两个输出流都重定向到一个名为output. 我使用>>是为了避免同时写入。
$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile
Run Code Online (Sandbox Code Playgroud)
这似乎有效。这种方法有什么危险吗?
我正在使用nohup如下所述在后台启动我的应用程序-
root@phx5qa01c:/bezook# nohup java -jar ./exhibitor-1.5.1/lib/exhibitor-1.5.1-jar-with-dependencies.jar -c file --fsconfigdir /opt/exhibitor/conf --hostname phx5qa01c.phx.qa.host.com > exhibitor.out &
[1] 30781
root@phx5qa01c:/bezook# nohup: ignoring input and redirecting stderr to stdout
Run Code Online (Sandbox Code Playgroud)
但每次看到这条信息——
nohup: ignoring input and redirecting stderr to stdout
Run Code Online (Sandbox Code Playgroud)
如果我看到这个消息会不会有什么问题?这是什么意思,我该如何避免?
在 bash 中:
$ echo hi 2>&1 1>/dev/null | cat
$
Run Code Online (Sandbox Code Playgroud)
在 zsh 中:
$ echo hi 2>&1 1>/dev/null | cat
hi
$
Run Code Online (Sandbox Code Playgroud)
有没有办法在重定向标准输出时只传输标准错误?
我运行了一个可执行文件 bash
./code > log
Run Code Online (Sandbox Code Playgroud)
它在终端上偶尔显示错误消息,而所有 printf 语句都进入日志文件。我像下面一样重新运行它
./code >& log
Run Code Online (Sandbox Code Playgroud)
现在,偶尔的错误消息也会进入日志。但是如果出现分段错误,它仍然显示在终端上。为什么?如何使消息Segmentation fault (core dumped)进入日志文件?
用户 $ bash --version
GNU bash,版本 4.2.24(1)-release (i686-pc-linux-gnu)
假设我运行了一些进程:
#!/usr/bin/env bash
foo &
bar &
baz &
wait;
Run Code Online (Sandbox Code Playgroud)
我像这样运行上面的脚本:
foobarbaz | cat
Run Code Online (Sandbox Code Playgroud)
据我所知,当任何进程写入 stdout/stderr 时,它们的输出永远不会交错——stdio 的每一行似乎都是原子的。这是如何运作的?什么实用程序控制每行的原子性?