我想将流程的标准输出和标准错误重定向到单个文件。我在巴什怎么做?
当前回答
简短回答:命令>文件名2>&1或命令>>文件名
说明:
考虑以下代码,该代码将单词“stdout”打印到stdout,将单词“tderror”打印到tderror。
$ (echo "stdout"; echo "stderror" >&2)
stdout
stderror
注意,“&”操作符告诉bash 2是文件描述符(指向stderr),而不是文件名。如果省略了“&”,该命令将stdout打印到stdout,并创建一个名为“2”的文件,并在其中写入stderror。
通过尝试上面的代码,您可以亲眼看到重定向操作符是如何工作的。例如,通过更改两个描述符1、2中的哪个文件被重定向到/dev/null,以下两行代码分别从stdout和stderror中删除所有内容(打印剩余内容)。
$ (echo "stdout"; echo "stderror" >&2) 1>/dev/null
stderror
$ (echo "stdout"; echo "stderror" >&2) 2>/dev/null
stdout
现在,我们可以解释为什么以下代码不产生输出的解决方案:
(echo "stdout"; echo "stderror" >&2) >/dev/null 2>&1
为了真正理解这一点,我强烈建议您阅读有关文件描述符表的网页。假设你已经完成了阅读,我们可以继续。注意,Bash从左到右处理;因此,Bash首先看到>/dev/null(这与1>/dev/null相同),并将文件描述符1设置为指向/dev/null而不是stdout。完成此操作后,Bash向右移动,看到2>&1。这将文件描述符2设置为指向与文件描述符1相同的文件(而不是指向文件描述符1本身!!!!(有关详细信息,请参阅此指针资源))。由于文件描述符1指向/dev/null,文件描述符2指向与文件描述符1相同的文件,因此文件描述符2现在也指向/dev/null。因此,两个文件描述符都指向/dev/null,这就是为什么不呈现输出。
为了测试您是否真正理解这个概念,请尝试在切换重定向顺序时猜测输出:
(echo "stdout"; echo "stderror" >&2) 2>&1 >/dev/null
标准错误
这里的理由是,从左到右计算,Bash看到2>&1,因此将文件描述符2设置为指向与文件描述符1相同的位置,即stdout。然后,它将文件描述符1(记住>/dev/null=1>/dev/null)设置为指向>/dev/null,从而删除通常发送到标准输出的所有内容。因此,我们只剩下未发送到子shell中的stdout的代码(括号中的代码),即“stderror”。值得注意的是,尽管1只是指向stdout的指针,但通过2>&1将指针2重定向到1不会形成指针链2->1->stdout。如果这样做了,作为将1重定向到/dev/null的结果,代码2>&1>/dev/null将给出指针链2->1->/dev/null,因此代码将不会生成任何内容,与我们上面看到的相反。
最后,我要指出,有一种更简单的方法可以做到这一点:
从这里的第3.6.4节中,我们可以看到我们可以使用运算符&>来重定向stdout和stderr。因此,要将任何命令的stderr和stdout输出重定向到\dev\null(这会删除输出),只需键入$command&>/dev/null或者在我的例子中:
$ (echo "stdout"; echo "stderror" >&2) &>/dev/null
关键要点:
文件描述符的行为类似于指针(尽管文件描述符与文件指针不同)将文件描述符“a”重定向到指向文件“f”的文件描述符“b”,会导致文件描述符“a”指向与文件描述符b-file“f”相同的位置。它不会形成指针链a->b->f由于以上原因,顺序很重要,2>&1>/dev/null是!=>/dev/null 2>&1。一个生成输出,另一个不生成!
最后看看这些伟大的资源:
重定向的Bash文档,文件描述符表的解释,指针介绍
其他回答
简短回答:命令>文件名2>&1或命令>>文件名
说明:
考虑以下代码,该代码将单词“stdout”打印到stdout,将单词“tderror”打印到tderror。
$ (echo "stdout"; echo "stderror" >&2)
stdout
stderror
注意,“&”操作符告诉bash 2是文件描述符(指向stderr),而不是文件名。如果省略了“&”,该命令将stdout打印到stdout,并创建一个名为“2”的文件,并在其中写入stderror。
通过尝试上面的代码,您可以亲眼看到重定向操作符是如何工作的。例如,通过更改两个描述符1、2中的哪个文件被重定向到/dev/null,以下两行代码分别从stdout和stderror中删除所有内容(打印剩余内容)。
$ (echo "stdout"; echo "stderror" >&2) 1>/dev/null
stderror
$ (echo "stdout"; echo "stderror" >&2) 2>/dev/null
stdout
现在,我们可以解释为什么以下代码不产生输出的解决方案:
(echo "stdout"; echo "stderror" >&2) >/dev/null 2>&1
为了真正理解这一点,我强烈建议您阅读有关文件描述符表的网页。假设你已经完成了阅读,我们可以继续。注意,Bash从左到右处理;因此,Bash首先看到>/dev/null(这与1>/dev/null相同),并将文件描述符1设置为指向/dev/null而不是stdout。完成此操作后,Bash向右移动,看到2>&1。这将文件描述符2设置为指向与文件描述符1相同的文件(而不是指向文件描述符1本身!!!!(有关详细信息,请参阅此指针资源))。由于文件描述符1指向/dev/null,文件描述符2指向与文件描述符1相同的文件,因此文件描述符2现在也指向/dev/null。因此,两个文件描述符都指向/dev/null,这就是为什么不呈现输出。
为了测试您是否真正理解这个概念,请尝试在切换重定向顺序时猜测输出:
(echo "stdout"; echo "stderror" >&2) 2>&1 >/dev/null
标准错误
这里的理由是,从左到右计算,Bash看到2>&1,因此将文件描述符2设置为指向与文件描述符1相同的位置,即stdout。然后,它将文件描述符1(记住>/dev/null=1>/dev/null)设置为指向>/dev/null,从而删除通常发送到标准输出的所有内容。因此,我们只剩下未发送到子shell中的stdout的代码(括号中的代码),即“stderror”。值得注意的是,尽管1只是指向stdout的指针,但通过2>&1将指针2重定向到1不会形成指针链2->1->stdout。如果这样做了,作为将1重定向到/dev/null的结果,代码2>&1>/dev/null将给出指针链2->1->/dev/null,因此代码将不会生成任何内容,与我们上面看到的相反。
最后,我要指出,有一种更简单的方法可以做到这一点:
从这里的第3.6.4节中,我们可以看到我们可以使用运算符&>来重定向stdout和stderr。因此,要将任何命令的stderr和stdout输出重定向到\dev\null(这会删除输出),只需键入$command&>/dev/null或者在我的例子中:
$ (echo "stdout"; echo "stderror" >&2) &>/dev/null
关键要点:
文件描述符的行为类似于指针(尽管文件描述符与文件指针不同)将文件描述符“a”重定向到指向文件“f”的文件描述符“b”,会导致文件描述符“a”指向与文件描述符b-file“f”相同的位置。它不会形成指针链a->b->f由于以上原因,顺序很重要,2>&1>/dev/null是!=>/dev/null 2>&1。一个生成输出,另一个不生成!
最后看看这些伟大的资源:
重定向的Bash文档,文件描述符表的解释,指针介绍
“最简单”的方法(仅限Bash 4):
ls * 2>&- 1>&-
看看这里。应该是:
yourcommand &> filename
它将标准输出和标准错误重定向到文件名。
奇怪的是,这是有效的:
yourcommand &> filename
但这会产生语法错误:
yourcommand &>> filename
syntax error near unexpected token `>'
您必须使用:
yourcommand 1>> filename 2>&1
在考虑使用exec2>&1之类的情况下,如果可能的话,我发现使用如下Bash函数重写代码更容易阅读:
function myfunc(){
[...]
}
myfunc &>mylog.log
推荐文章
- 如何在shell管道中使用“jq”?
- 如何使用jq从JSON获得键名
- 图形化对?
- 我如何能匹配一个字符串与正则表达式在Bash?
- 为什么cURL返回错误“(23)Failed writing body”?
- 在Unix shell中计算一列数字
- 在bash脚本中否定if条件
- 如何撤消“set -e”使bash立即退出,如果任何命令失败?
- 如何在docker映像的新容器中运行bash ?
- 管道命令输出到tee,但也保存退出代码的命令
- 如何自动添加用户帐户和密码与Bash脚本?
- 是否有方法按列“uniq”?
- 如何在bash脚本中检查文件名的扩展名?
- 使用bash的变量中第一个大写字符
- 我如何才能快速和所有的数字在一个文件?