在 bash 中重定向 stdout 和 stderr 的正确方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18624463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:28:06  来源:igfitidea点击:

What's the correct way to redirect both stdout and stderr in bash?

bashzsh

提问by Cuadue

Here's the concrete task I'm trying to accomplish. zsh behaves the way I like

这是我要完成的具体任务。zsh 的行为方式我喜欢

$ zsh
$ which clang > /dev/null 2&>1 && echo clang || echo gcc
clang
$ which doesntexist > /dev/null 2&>1 && echo doesntexist || echo gcc
gcc

But, in bash:

但是,在 bash 中:

$ bash
$ which clang > /dev/null 2&>1 && echo clang || echo gcc
gcc

Here's the general case:

这是一般情况:

$ which clang > /dev/null 2&>1; echo $?
1
$ which clang; echo $?
/usr/bin/clang
0

There's something wrong with how I'm redirecting output. What's the right way?

我重定向输出的方式有问题。什么是正确的方法?

回答by konsolebox

I think you're redirecting the wrong way:

我认为您重定向的方式错误:

which clang > /dev/null 2&>1; echo $?

Should be

应该

which clang > /dev/null 2>&1; echo $?

It's probably how either shells allow the former method. In bash it's not the right way. Bash would interpret it instead like:

这可能是两种 shell 允许前一种方法的方式。在 bash 中,这不是正确的方法。Bash 会将其解释为:

which clang >/dev/null 2 &>1; echo $?

In which 2is added as an argument.

其中2作为参数添加。

You can verify that by creating a function like

您可以通过创建一个函数来验证这一点

e() { echo "$@" >e.log; }

And call it as:

并将其称为:

e 1 >/dev/null 2&>/dev/null

And you would get 1 2in e.log.

你会进入1 2e.log。

In bash it's also simpler if you call your command like this:

在 bash 中,如果您像这样调用命令,它也会更简单:

which clang &>/dev/null; echo $?

Also rather than calling an external binary like which, use type -Pinstead. No need to redirect stderr output too.

也不要调用像 那样的外部二进制文件whichtype -P而是使用。也不需要重定向 stderr 输出。

type -P clang >/dev/null; echo $?

回答by Phil

You're using zsh's &>operator, which redirects stderr and stdout. The way you've used it suggests you meant ... > /dev/null 2>&1instead.

您正在使用 zsh 的&>运算符,它重定向 stderr 和 stdout。你使用它的方式表明你的意思... > /dev/null 2>&1

I would do this as:

我会这样做:

$ cc=$( type -P clang gcc othercc | head -n 1 )
$ echo $cc
/usr/bin/clang

回答by Aleks-Daniel Jakimenko-A.

Use this:

用这个:

which gcc >& /dev/null && echo gcc || echo clang

Also you can use this:

你也可以使用这个:

[[ $(which gcc) ]] && echo gcc || echo clang # prints gcc
[[ $(which clang) ]] && echo gcc || echo clang # prints clang

This works because in [[ ]]empty strings are falsey.

这是有效的,因为在[[ ]]空字符串中是假的。