Bash: tee を使用しているときに、コマンドの出力が画面にのみ書き込まれ、別のファイルには書き込まれません。その理由は何でしょうか?

Bash: tee を使用しているときに、コマンドの出力が画面にのみ書き込まれ、別のファイルには書き込まれません。その理由は何でしょうか?

いくつかの FTP 接続エラーをトラブルシューティングするために、リモート frp サーバーに無限に接続し、そこから 1 つのファイルを取得する bash スクリプトを作成するように指示されました。

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上にあるためSTDERR、 には表示されないからです。

これはデフォルトではパイプを経由せず、tty代わりに - ご覧のとおり - に送られます。送信したい場合は両方 STDOUTSTDERRパイプの には を使用STDINする必要があります|&。例:

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

記憶が正しければ、これは bash と tcsh では機能します。標準的な sh の場合は、もう少し手間がかかりますが、それでも実行できます (ただし、やり方はすぐには思い出せません)。

編集(Anthony によるコメントが続きます。ありがとうございます! - MadHatter):

POSIX 互換シェルの構文 (でも動作するはずですsh) は次のようになります。

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

関連情報