execリダイレクションを含むコマンドリストをリダイレクトする場合、exec> / dev / nullは後で適用されるようには見えません:
{ exec >/dev/null; } >/dev/null; echo "Hi"
「こんにちは」と印刷されます。
{}
コマンドリストはパイプラインの一部でない限り、サブシェルとは見なされないためexec >/dev/null
、現在のシェル環境内でコマンドリストを適用する必要があるという印象を受けました。
これを次のように変更すると:
{ exec >/dev/null; } 2>/dev/null; echo "Hi"
期待どおりの出力はありません。将来のコマンドでも、ファイル記述子1は/ dev / nullをポイントしたままです。これは再実行によって示されます:
{ exec >/dev/null; } >/dev/null; echo "Hi"
出力されません。
私は台本を作ってそれを追跡しようとしましたが、ここで何が起こっているのか正確にはわかりません。
このスクリプトの各ポイントで、STDOUTファイル記述子はどうなりますか?
編集:私のstrace出力の追加:
read(255, "#!/usr/bin/env bash\n{ exec 1>/de"..., 65) = 65
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD) = 0
fcntl(1, F_DUPFD, 10) = 10
fcntl(1, F_GETFD) = 0
fcntl(10, F_SETFD, FD_CLOEXEC) = 0
dup2(3, 1) = 1
close(3) = 0
close(10) = 0
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD) = 0
fcntl(1, F_DUPFD, 10) = 10
fcntl(1, F_GETFD) = 0
fcntl(10, F_SETFD, FD_CLOEXEC) = 0
dup2(3, 1) = 1
close(3) = 0
dup2(10, 1) = 1
fcntl(10, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(10) = 0
fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, TCGETS, 0x7ffee027ef90) = -1 ENOTTY (Inappropriate ioctl for device)
write(1, "hi\n", 3) = 3
;
後}
に迷いがあり、結局> /dev/null
、複合リスト{}
に適用しないという意味が変わります。
close(10)
。straceを実行したスクリプトの内容全体を投稿することもできますか?