cd
別のコマンドからリダイレクトされたディレクトリ名を受け入れようとしています。これらの方法はどちらも機能しません。
$ echo $HOME | cd
$ echo $HOME | xargs cd
これは動作します:
$ cd $(echo $HOME)
最初のコマンドセットが機能しないのはなぜですか?
cd
別のコマンドからリダイレクトされたディレクトリ名を受け入れようとしています。これらの方法はどちらも機能しません。
$ echo $HOME | cd
$ echo $HOME | xargs cd
これは動作します:
$ cd $(echo $HOME)
最初のコマンドセットが機能しないのはなぜですか?
回答:
cd
外部コマンドではなく、シェルの組み込み関数です。現在のシェルのコンテキストで実行されますが、外部コマンドのように、fork / exec'dコンテキストでは別のプロセスとして実行されません。
3番目の例は、シェルがcd
組み込み関数を呼び出す前に変数とコマンド置換を展開し、その引数としてcd
の値を受け取るため、${HOME}
機能します。
POSIXシステムにはバイナリがありますcd
-私のFreeBSDマシンでは、に/usr/bin/cd
ありますが、あなたが思っていることはしません。バイナリcd
を呼び出すと、シェルはバイナリをfork / execします。これにより、実際に作業ディレクトリが渡した名前に変更されます。ただし、そうするとすぐにバイナリが終了し、fork / exec'dプロセスが消え、シェルに戻ります。シェルは開始前のディレクトリにあります。
cd
コマンドを?
既存の良い答えに加えて、パイプが新しいプロセスを分岐することにも言及する価値があります。新しいプロセスには独自の作業ディレクトリがあります。したがって、これを実行しようとしても機能しません。
echo test | cd /
したがって、シェルがこのコマンドから戻った後は/フォルダーに移動しません。
a | b
ている場合でも、少なくとも1つはシェルプロセスで実行されませんが、どのコマンドであるかは保証されません。AT&Tで例えば、あるいは、あなたのコードがに/そこにあなたを取るので、現在のシェルプロセスで実行されます。a
b
ksh
zsh
bash -O lastpipe
b
すでに与えられている正しい答えに加えて:bashを実行して、cdのような「コマンド」が何であるかを知りたい場合は、typeを使用できます。
$ type cd
cd is a shell builtin
または理由:
$ type time
time is a shell keyword
たとえば、gnu timeは通常、すでにお気に入りのディストリビューションに含まれています:
$ which time
/usr/bin/time
オーケーオーケーあなたはアイデアを得る、そして一体何がタイプですか?
$ type type
type is a shell builtin
bashのマニュアルスニペットを次に示します。
type [-aftpP] name [name ...]
With no options, indicate how each name would be interpreted if used as a
command name. If the -t option is used, type prints a string which is one of
alias, keyword, function, builtin, or file if name is an alias, shell
reserved word, function, builtin, or disk file, respectively. If the name is
not found, then nothing is printed, and an exit status of false is returned.
If the -p option is used, type either returns the name of the disk file that
would be executed if name were specified as a command name, or nothing if
‘‘type -t name’’ would not return file. The -P option forces a PATH search
for each name, even if ‘‘type -t name’’ would not return file. If a command
is hashed, -p and -P print the hashed value, not necessarily the file that
appears first in PATH. If the -a option is used, type prints all of the
places that contain an executable named name. This includes aliases and
functions, if and only if the -p option is not also used. The table of
hashed commands is not consulted when using -a. The -f option suppresses
shell function lookup, as with the command builtin. type returns true if any
of the arguments are found, false if none are found.
他の人が言ったcd
ように、外部プログラムではなくシェル組み込みコマンドであるため、機能しません。したがって、パイプで入力できる標準入力はありません。
しかし、たとえそれが機能したとしても、あなたが望むことはしません:パイプは新しいプロセスを生成し、最初のコマンドの標準出力を2番目のコマンドの標準入力にリダイレクトします。したがって、新しいプロセスのみが現在の動作を変更しますディレクトリ; これが最初のプロセスに影響することはありませんでした。
read
通常(常に?)シェル組み込みです。cd
stdin を無視するのは事実ですが、これは組み込みであるためではありません。
もう1つのオプションは、1つのコマンドのstdoutを2番目のコマンドのコマンドライン引数として配置するバックティックであり、より移植性があり$(...)
ます。例えば:
cd `echo $HOME`
またはより一般的に;
cd `anycommand -and whatever args`
バックティックの使用は、コマンドを実行してコマンドラインの出力を置き換えるシェルに依存することに注意してください。ほとんどのシェルがサポートしています。
$(...)
機能することをすでに述べています。代わりにバッククォートをお勧めするのは良いアドバイスではないと思います。クォートのルールがより複雑で、一般にエラーが発生しやすいためです。(Bashリファレンスマニュアルのセクション3.5.4「コマンドの置換」を参照してください。)
$(...)
あるシステムではサポートするが別のシステムではサポートしないシェルは本当にありますか??
$(…)
ます。POSIXシェルを使用しないシステム(つまり、本物のBourneシェルを使用するシステム)は非常に古いものです。/bin/sh
Bourneシェルがあり/usr/xpg4/bin/sh
、POSIXシェルを取得するなどの別のパスが必要なシステムでさえ、現在ではまれです。古代のunix boxenを専門的に管理していない人にバックティックを勧めることは、彼らを傷つけています。