繁体   English   中英

将标准错误发送到标准输出不起作用

[英]Sending standard error to standard out not working

我在获取将标准错误发送到标准输出的命令时遇到了麻烦。 我打算将其放在cron中,但现在只是手动运行。

/home/backups/backup_scripts/backup.sh 2>&1 >> /var/log/backups/backup.log

我希望该日志文件包含任何已打印为标准输出的消息,但是该日志文件仅显示标准输出,并且控制台输出显示了错误。

我在这里做错了什么?

重定向的顺序很重要。 您应该将其更改为:

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1 

这会将stdout重定向到/var/log/backups/backup.log ,然后将stderr重定向到stdout(这将进入文件)。

您还可以使用以下简短形式:

/home/backups/backup_scripts/backup.sh &>> /var/log/backups/backup.log

&>>file在语义上等效于>>file 2>&1

这是由于重定向的顺序而发生的。 2>&1表示“将标准错误重定向到标准输出的当前位置”。 它们从左到右进行处理,因此首先将标准错误重定向到当前标准输出(仍然是终端),然后将标准输出重定向到文件。 如果您将订单切换为阅读

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1

它应该做你想要的。 如果您的shell是bash,则它具有一个可同时重定向标准输出和标准错误的快捷方式: command &> file将它们都重定向到一个文件, command &>> file将它们都追加到一个文件。 bash手册中也提到了这种顺序依赖性

请注意,重定向的顺序很重要。 例如,命令

 ls > dirlist 2>&1 

将标准输出和标准错误都定向到文件目录,同时命令

 ls 2>&1 > dirlist 

仅将标准输出定向到文件dirlist,因为在将标准输出重定向到dirlist之前,从标准输出中复制了标准错误。

我认为对于文件描述符和重定向的工作方式存在一些误解。 内核对系统上所有打开的文件都有一个大表,其中包含文件偏移量,状态标志和文件本身的名称。 然后,每个进程都有一个表,该表将文件描述符号映射到该全局表中的条目。

在进行任何重定向之前,全局表可能看起来像这样

A: TERMINAL

进程表看起来像

0: A
1: A
2: A

因为描述符编号0、1和2分别是stdin,stdout和stderr。

然后处理2>&1重定向。 这将更改过程表,以使2包含指向与1相同的全局条目的点。但是,它们已经相同,因此没有任何反应。

处理>> /var/log/backups/backup.log重定向时。 首先,在过程表中打开文件并将其分配给文件描述符3,使表看起来像

A: TERMINAL
B: /var/log/backups/backup.log

0: A
1: A
2: A
3: B

然后将标准输出更改为指向新打开的文件(就像完成了1>&3一样),因此过程表现在

0: A
1: B
2: A
3: B

请注意,2(stderr)仍指向终端。

当以其他顺序进行重定向时, >> /var/log/backups/backup.log之后的表看起来相同。

0: A
1: B
2: A
3: B

然后2>&1重定向将2指向

0: A
1: B
2: B
3: B

所以现在stdout和stderr都转到该文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM