残念なことに、私が見つけたのはリダイレクトの構文であるか、リダイレクトがどのように機能するかについての表面的な情報だけでした。
私が知りたいのは、パイプやリダイレクトを使用するときにbashが実際にどのように変わるかですstdin
。たとえば、次を実行する場合:stdout
stderr
ls -la > diroutput.log
stdout
にどのように変わりますかls
?diroutput.log
私はこれが次のように動作すると思います。
- Bash を実行して
fork(2)
独自のコピーを作成します。 - bashプロセスをフォークして、次のようなものを有効にします
stdout
。diroutput.log
freopen(3)
- 分岐されたbashプロセスが実行されるか、
execve(2)
同様のexec機能が独自に置き換えられ、bash設定を使用するようになりましたls
。stdout
しかし、それは私の経験に基づいた推測です。
答え1
strace -f
私はこの問題を解決するためにCを使って簡単な概念証明を書くことができました。
execve
私が思ったように、bashは呼び出す前に子プロセスのファイル記述子を操作するようです。
動作原理はls -la > diroutput.log
おおよそ次のとおりです。
- バッシュ通貨
fork(2)
- 分岐されたbashプロセスは出力リダイレクトを確認し
diroutput.log
ますopen(2)
。 - フォークされたbashプロセスは、ファイル記述子をシステムコール
stdout
に置き換えます。dup2(2)
execve(2)
bashはそれを置き換える実行可能イメージを呼び出して、すでに設定されてls
いるイメージを継承します。stdout
関連するシステムコールは次のとおりです(strace
出力)。
6924 open("diroutput.log", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
6924 dup2(3, 1) = 1
6924 close(3) = 0
6924 execve("/bin/ls", ["ls", "-la"], [/* 77 vars */]) = 0