Bash
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 =====------
你能找到它沒有寫入日誌的原因嗎?
提前致謝,
原因是雖然
echo
語句轉到STDOUT
,因此通過管道發送到tee
,但您從wget
命令中看到的“輸出”是 onSTDERR
,但不是。預設情況下,這不會通過管道,而是通過 - 如您所見 - 來
tty
代替。如果你想同時發送和STDOUT
發送STDERR
到管道STDIN
,你應該使用|&
,例如/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv |& tee -a $log
如果有記憶的話,這在 bash 和 tcsh 中有效。對於 bog 標準 sh 來說,它需要做更多的工作,但仍然可以完成(儘管我不記得怎麼做)。
編輯(安東尼,他的評論如下;謝謝!- MadHatter):
POSIX 兼容 shell 的語法(也應該適用於
sh
)將是:/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv 2>&1 | tee -a $log