ファイルを読み込み、出力全体をファイルにリダイレクトしています。特定の式のstdoutとstderrを次のように画面にリダイレクトしたいと思います(例)。
#!/bin/bash
OLDIFS=$IFS
while IFS='|'
while read fname fpath dname dpath ; do
echo "$fname" >> redirect to screen
echo "$fpath"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >> redirect to screen
done > logfile
試してみましたが>$(tty)
成功しませんでした。これも機能しません。
while read fname fpath dname dpath; do
echo "$fname" >&1
echo "$fpath"
echo "$dname"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >&1
done > logfile
tee
リダイレクトされるため使用できません。みんな画面に出力します。この目標をどのように達成できますか?
答え1
while …; do echo "$fname" >&1 done > logfile
コマンドの標準出力はecho
標準出力にリダイレクトされます。つまり、>&1
無動作です。 inは、神秘的に選択された外部範囲ではなく、それを使用するコマンドのファイル記述子1を1
指定します。>&1
外部スコープから使用可能なファイルにリダイレクトするには、その外部スコープにファイル記述子を複製し、重複したファイル記述子をリダイレクトしないでください。
while read fname fpath dname dpath; do
echo "$fname" >&3
echo "$fpath"
echo "$dname"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >&3
done 3>&1 >logfile
ループのリダイレクト順序に注意してください。まず、ファイルディスクリプタ1(標準出力)が現在位置する場所にファイルディスクリプタ3が作成され、ファイルディスクリプタ1が別の場所にリダイレクトされます。
別の記述子からログファイルを開くこともできます。
while read fname fpath dname dpath; do
echo "$fname"
echo "$fpath" >&3
echo "$dname" >&3
echo "$dpath" >&3
diff "$fpath/$fname" "$dpath/$dname"
done 3>logfile
答え2
ループwhile
が非対話型なので、ttyはありません。ループに入る前にttyデバイスを保存する必要があります。だからあなたは次のようなものを得るでしょう:
my_tty=$(tty)
while read fname fpath dname dpath ; do
echo "$fname" | tee ${my_tty}
echo "$fpath"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" | tee ${my_tty}
done > logfile