コマンドのパス名出力を「cd」にリダイレクトできないのはなぜですか?

コマンドのパス名出力を「cd」にリダイレクトできないのはなぜですか?

cd他のコマンドからリダイレクトするディレクトリ名を受け入れようとしています。次のいずれの方法も機能しません。

$ echo $HOME | cd
$ echo $HOME | xargs cd

これは働きます:

$ cd $(echo $HOME)

最初のコマンドセットが機能しないのはなぜですか?このように失敗する他のコマンドもありますか?

答え1

cd外部コマンドではなく、シェル組み込み機能です。外部コマンドなど、ブランチ/実行コンテキストでは、別のプロセスではなく、現在のシェルのコンテキストで実行されます。

3番目の例は、組み込み関数を呼び出す前にシェルが変数とコマンド置換を拡張して値を引数として受け取るためにcd機能します。cd${HOME}

POSIXシステムするバイナリがありますcd。私のFreeBSDコンピュータにバイナリがありますが、/usr/bin/cdあなたが思うように動作しません。バイナリを呼び出すと、cdシェルはバイナリを分岐/実行し、実際には作業ディレクトリが渡した名前に変更されます。ただし、これが完了するとバイナリが終了し、分岐/実行されたプロセスが消えてシェルに戻ります。シェルは起動前のディレクトリに残ります。

答え2

cd標準入力は読み込まれません。これが最初の例がうまくいかない理由です。

xargsスタンドアロン実行可能ファイルの名前であるコマンド名が必要です。cdシェル組み込みでなければならず、実行可能であれば効果はありません(該当するディレクトリに変更できることを確認し、自動マウント可能なディレクトリに潜在的な副作用があることを確認する以外)。これが2番目の例がうまくいかない理由です。

答え3

既存の良い答えに加えて、パイプが別の作業ディレクトリを持つ新しいプロセスを分岐することにも言及する価値があります。したがって、これを試しても機能しません。

echo test | cd /

したがって、シェルがコマンドから返された後は、/フォルダにありません。

答え4

他の人が言ったように、cdこれは外部プログラムではなくシェル組み込みなので動作しません。したがって、パイプする標準入力はありません。

しかし、動作しても必要なことは行われません。パイプは新しいプロセスを生成し、最初のコマンドの標準出力を2番目のコマンドの標準入力にリダイレクトするので、新しいプロセスだけが現在の作業ディレクトリを変更しません。何らかの方法で最初のプロセスに影響を与えます。

関連情報