このようなコマンドは、cd
ディレクトリを変更するために出力をパイプできません。コマンドライン引数が必要です。
から読み取ると、このコマンド(および、、&cd
などの類似コマンド)が他のほとんどのコマンドのように機能しないのはなぜですか?ディレクトリを変更するために標準入力を読み取らないようにするロジックは何ですか?mv
cp
rm
STDIN
最高私が見つけることができる答え指摘した:
cd は外部コマンドではありません。シェル組み込み関数です。外部コマンドなど、ブランチ/実行コンテキストでは、別のプロセスではなく、現在のシェルのコンテキストで実行されます。
しかし、私に上記の答えは実際にはまったく説明しません。cd
処理STDIN
がで読んだ他の多くのコマンドと異なる理由は何ですかSTDIN
?
答え1
読み取りコマンドは、stdin
ほとんど常にテキストデータストリームを変換されたデータストリームに変換するプログラムであるフィルタシリーズに属します。
cat
、、、sed
は、awk
これらの「フィルタ」の良い例gzip
です。sh
参照されるコマンドはcp
フィルタでmv
はなく、rm
渡された引数(この場合はファイルまたはディレクトリ)を使用して操作を実行するコマンドです。
このcd
コマンドは、引数を取る(または指定されていない場合はデフォルトの引数をエミュレートするという点で)通常は何も出力しませんが、場合によっては(stdout
contentを使用するときなど)一部を出力できるという点で似ていますCDPATH
。
stdinからターゲットディレクトリを取得するバリアントを作成したい場合でも、Bournecd
シェルのパイプで使用しても効果はありません。コマンドの最後のコンポーネントはサブシェルで実行され、新しいディレクトリに対する変更は現在のシェルには影響しません。例: 使用できますが使用できません , , , , ...dash
bash
echo /tmp | cd
ksh93
bash
dash
zsh
sh
cd <(echo /tmp)
プロセス置換(少なくともksh
、bash
)をサポートするシェルzsh
で使用できますが、cd $(echo tmp)
興味がある唯一のユースケースは次のとおりです。
echo tmp | (cd ; pwd)
最後に、引数が指定されていないが予想される動作がディレクトリをユーザーのホームディレクトリに変更する場合、または引数が指定されていないが予想される動作が名前を読み取る場合を説明するために、これらのバリエーションが必要です。 stdinのターゲットディレクトリ。信頼できる決定方法がないので、これは当然のことです。
答え2
コマンドライン引数はstdinとは全く異なります。両方を使用するコマンドも通常、さまざまな目的で使用されます。例えばcat
:
echo foo bar | cat # outputs "foo bar"
cat foo bar # looks for files named "foo" and "bar", and concatenates them (if found)
stdinで読んでいる他のほとんどのコマンドを見ると、同様のことがわかります。つまり、引数と stdin を入れ替えて処理するのではなく、コマンドにさまざまな種類の情報を提供する方法で処理します。
どちらにしても、同じ種類の情報を取得できるコマンドがありますが、そのような場合でも、通常どのコマンドを使用するかを知らせるオプションを指定する必要があります。たとえば、perl
特に指示がない限り、stdinで読み込むプログラムは次のようになります。
echo 'print 1' | perl # runs "print 1" as a perl program, which prints "1"
perl -e 'print 1' # runs "print 1" as a perl program, which prints "1"
perl print 1 # tries to run a file named "print" as a script, giving it the argument "1"
...だから質問の前提が間違っていると思います。ほとんどのコマンドは、引数から得られるのと同じ種類の情報を標準入力から得ることができないので、cd
その点ではまれではありません。