我有一个我认为正在输出的命令,stderr
因为当我重定向stdout
到时/dev/null
,我仍然将输出打印到屏幕上。
但是,当我重定向stderr
到时/dev/null
,我也会将输出打印到屏幕上。
此外,当我将所有输出重定向到/dev/null
then 时,它会按预期工作。
怎么会这样?应该1>
并2>
至少抓住一些吗&>
?
下面是一个例子:
$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 1>/dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 2>/dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles &>/dev/null
$
要复制,请克隆我的项目:
➜ ~/D/w/tmp rm /tmp/fakehome
➜ ~/D/w/tmp mkdir /tmp/fakehome
➜ ~/D/w/tmp git clone https://github.com/mbigras/mb-fullstop
Cloning into 'mb-fullstop'...
remote: Counting objects: 150, done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 150 (delta 49), reused 147 (delta 46), pack-reused 0
Receiving objects: 100% (150/150), 24.06 KiB | 0 bytes/s, done.
Resolving deltas: 100% (49/49), done.
Checking connectivity... done.
➜ ~/D/w/tmp cd mb-fullstop
➜ mb-fullstop master ✓ git checkout fix-git-logging-to-stderr
Branch fix-git-logging-to-stderr set up to track remote branch fix-git-logging-to-stderr from origin.
Switched to a new branch 'fix-git-logging-to-stderr'
➜ mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': Cloning into 'fake-dotfiles'...
➜ mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
➜ mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 1> /dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
➜ mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 2> /dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
➜ mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles &> /dev/null
➜ mb-fullstop fix-git-logging-to-stderr ✓
答案1
这是 Ruby 日志库的一个特性美沙酮由该脚本使用。它的行为有所不同,具体取决于标准输出和标准错误是否是终端。
参见initialize
方法cli_logger.rb
。正如评论中所描述的:
将错误类型消息记录到第二个设备的记录器;对于确保错误消息进入标准错误很有用。这对于做正确的事情来说应该是非常明智的。如果两个日志设备都是 tty,例如,一个用于标准错误,另一个用于标准输出,则消息在整个输出流中仅出现一次。换句话说,将显示记录的错误仅有的在标准误中。如果任一日志设备不是 tty,则所有消息都会发送到 +log_device+,只有错误会发送到 +error_device+
您可能会对“做正确的事非常聪明”的说法提出异议。日志模块的更明智的默认设置是记录到 stderr 并忽略 stdout。