出力がパイプで接続されている場合、「cd」が何の効果もないのはなぜですか?

出力がパイプで接続されている場合、「cd」が何の効果もないのはなぜですか?

誤って入った。

cd /tmp | tail

私が意図したのは確かにそうではありません。しかし、驚くべきことに、私はその後ディレクトリを変更しませんでした。なぜこれですか?比較しよう

cd /tmp > /tmp/foo

するディレクトリ変更が発生するため、それ自体は出力リダイレクトではありません。ここで何が起こっているのでしょうか?

答え1

パイプラインにはサブシェルが含まれ、その一部は親シェル内で実行されないため、親シェルプロセスの作業ディレクトリには影響しません。 ZSHは次のように動作します。

% cd /tmp
% cd /var/tmp | tail
% pwd
/tmp
% echo foo | cd /var/tmp
(pwd now: /var/tmp)
% cd /tmp
% echo foo | cd /var/tmp | echo bar
bar
% pwd
/tmp
% 

cdディレクトリはパイプラインの最後のコマンドでのみ変更されます。これは親シェルで実行されるため、プロセスの作業ディレクトリが変更されます。

この機能の有用な用途には、通常、明示的なサブシェルとその中で実行されるコマンドが含まれます。

dowork | ( cd elsewhere && domorework ) | andyetmore

また、出力があちこちに散布されるのが気に入らない場合や、他の仮想的な混乱が発生しcdない限り、動作すると仮定するのではなく、呼び出しをエラーにしてください。rsync/

関連情報