離れた絶対的な dup(2)
存在する強く打つfd
{10,11,12}
から出力実際のユースケースその後すぐに閉じます。ここ:
$ cat tags
desktop-19.9.0
foobar-1.2.3
desktop-22.9.0
mobile-24.10.0
desktop-18.9.0
desktop-21.9.0
mobile-23.10.0
foobar-1.2.4
desktop-17.8.0
desktop-20.8.0
mobile-22.9.0
desktop-16.8.0
desktop-19.8.0
mobile-21.9.0
foobar-1.2.5
desktop-15.7.0
desktop-18.7.0
mobile-20.8.0
desktop-14.7.0
desktop-17.7.0
mobile-19.8.0
desktop-13.6.0
desktop-16.6.0
mobile-18.7.0
foobar-1.2.6
desktop-12.6.0
desktop-15.6.0
mobile-17.7.0
desktop-11.5.0
desktop-14.5.0
mobile-16.6.0
desktop-10.5.0
desktop-13.5.0
mobile-15.6.0
desktop-9.4.0
desktop-12.4.0
mobile-14.5.0
desktop-8.4.0
desktop-11.4.0
mobile-13.5.0
desktop-7.3.0
foobar-1.2.7
desktop-10.3.0
mobile-12.4.0
desktop-6.3.0
desktop-9.3.0
mobile-11.4.0
desktop-5.2.0
desktop-8.2.0
mobile-10.3.0
desktop-4.2.0
desktop-7.2.0
mobile-9.3.0
desktop-3.1.0
desktop-6.1.0
mobile-8.2.0
desktop-2.1.0
desktop-5.1.0
mobile-7.2.0
desktop-1.0.0
foobar-1.2.8
desktop-4.0.0
mobile-6.1.0
cat tags | tee /dev/fd/{10,11,12} 10> >(
grep -w desktop | tail -n 3) 11> >(
grep -w mobile | tail -n 3) 12> >(
grep -w foobar | tail -n 3) 1>/dev/null
出力:
foobar-1.2.6
foobar-1.2.7
foobar-1.2.8
mobile-8.2.0
mobile-7.2.0
mobile-6.1.0
desktop-5.1.0
desktop-1.0.0
desktop-4.0.0
動作しますが、説明はありません。どのように動作しますか?。後ろで何が起こるのか?
なぜfd
自動的に終了するのかわかりません。明示的なオープン/クローズを使用して作成できますかfd
?
test -e /dev/fd/10 && echo open || echo close
close
編集する:
次のように単純化できます。
cat tags | tee >(
grep -w mobile | tail -n3) >(
grep -w desktop | tail -n3) >(
grep -w foobar | tail -n3) > /dev/null
システムコールのデバッグ:
$ strace -fff -o log bash -c '
cat tags | tee >(
grep -w mobile | tail -n3) >(
grep -w desktop | tail -n3) >(
grep -w foobar | tail -n3) > /dev/null'
$ less log.*
$ grep dup log*
log.2476802:dup2(4, 1) = 1
log.2476803:dup2(3, 0) = 0
log.2476803:dup2(4, 63) = 63
log.2476803:dup2(4, 62) = 62
log.2476803:dup2(4, 61) = 61
log.2476803:dup2(3, 1) = 1
log.2476804:dup2(3, 0) = 0
log.2476805:dup2(4, 1) = 1
log.2476806:dup2(3, 0) = 0
log.2476807:dup2(3, 0) = 0
log.2476808:dup2(4, 1) = 1
log.2476809:dup2(3, 0) = 0
log.2476810:dup2(3, 0) = 0
log.2476811:dup2(4, 1) = 1
log.2476812:dup2(3, 0) = 0
$ LANG=C grep close log.*
log.2476801:close(3) = 0
log.2476801:close(4) = 0
log.2476801:close(4) = -1 EBADF (Mauvais descripteur de fichier)
log.2476801:close(3) = -1 EBADF (Mauvais descripteur de fichier)
log.2476802:close(4) = 0
log.2476802:close(3) = 0
log.2476802:close(1) = 0
log.2476802:close(2) = 0
log.2476803:close(3) = 0
log.2476803:close(4) = 0
log.2476803:close(3) = 0
log.2476803:close(4) = 0
log.2476803:close(3) = 0
log.2476803:close(4) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(3) = 0
log.2476803:close(4) = 0
log.2476803:close(5) = 0
log.2476803:close(0) = 0
log.2476804:close(63) = 0
log.2476804:close(4) = -1 EBADF (Mauvais descripteur de fichier)
log.2476804:close(3) = 0
log.2476804:close(3) = -1 EBADF (Mauvais descripteur de fichier)
[...]
ベストアンサー1
書くときtee /dev/fd/{10,11,12} 10> (…) 11> (…) 12> (…)
シェルは最初にパイプを作成し、パイプを継承する子プロセスを作成し、未使用のパイプの終わりを閉じてファイルディレクトリを再マップします。その後、コマンドが実行されると/dev/fd/10
(または11または12)を開くことができます。
カーネルは利用可能なファイル記述子のみを表示します。リダイレクトの範囲は10>
そのコマンドに制限されます。
strace
表示したい場合は、たとえば表示することをお勧めしますdup2
。strace -ff bash -c "cmd1 >(cmd2)" 2>&1 | grep dup