Bash:使用 tee 时,命令的输出仅写入屏幕而不是写入其他文件,可能是什么原因?

Bash:使用 tee 时,命令的输出仅写入屏幕而不是写入其他文件,可能是什么原因?

为了解决某些 ftp 连接错误,我被要求编写一个 bash 脚本,该脚本将无限连接到远程 frp 服务器并从那里获取一个文件。

ftpuser="ftpuser" 
ftppasswd="ftppasswd" 
ftpsrv="download.akamai.com" 
log="/var/log/test_ftp_akamai.log" 
function print_log { 
        echo $(date +'%d-%m-%y %H:%M:%S') $* >> $log 
} 

while true 
do print_log "-----===== Start =====------" | tee -a $log 
/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv | tee -a $log 
sleep 2 | tee -a $log 
print_log "-----===== Done =====------" | tee -a $log 
done

脚本运行正常,但wget打印到屏幕上的行输出也应该被tee写入日志,但由于某种原因,它并没有被写入日志。

例子:

[root@sjorigin1 ~]# tailf /var/log/test_ftp_akamai.log 
25-02-15 02:10:31 -----===== Start =====------
25-02-15 02:10:33 -----===== Done =====------
25-02-15 02:10:33 -----===== Start =====------
25-02-15 02:10:35 -----===== Done =====------

你能找到它没有写入日志的原因吗?

提前致谢,

答案1

原因是,尽管echo语句转到STDOUT,并因此通过管道发送到tee,但您从命令中看到的“输出”wget是 on STDERR,而事实并非如此。

默认情况下,它不会通过管道,tty而是转到 - 如您所见。如果您想发送两个都 STDOUT并且STDERR对于管道STDIN,您应该使用|&,例如

/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv |& tee -a $log

如果我没有记错的话,这在 bash 和 tcsh 中是可行的。对于 bog 标准 sh,这需要做更多工作,但仍然可以完成(尽管我不记得怎么做了)。

编辑(作者:Anthony,其评论如下;感谢!- MadHatter):

POSIX 兼容 shell 的语法(也适用于sh)如下:

/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv 2>&1 | tee -a $log

相关内容