web-dev-qa-db-ja.com

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

別のコマンドからリダイレクトされたディレクトリ名をcdに受け入れようとしています。これらの方法はどちらも機能しません。

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

これは機能します:

$ cd $(echo $HOME)

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

28
Jhonathan

cdは外部コマンドではなく、シェルの組み込み関数です。現在のシェルのコンテキストで実行され、外部コマンドのように、フォーク/実行されたコンテキストで別のプロセスとして実行されません。

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

POSIXシステムdoはバイナリcdを持っています-私のFreeBSDマシンでは/usr/bin/cdにありますが、あなたが思っていることをしていません。バイナリcdを呼び出すと、シェルはバイナリをfork/execします。これにより、実際に作業ディレクトリが指定した名前に変更されます。ただし、そうするとすぐにバイナリが終了し、forked/exec'dプロセスが消えて、シェルが起動前のディレクトリに残っているシェルに戻ります。

34
D_Bye

cdは標準入力を読み取りません。これが、最初の例が機能しない理由です。

xargsにはコマンド名、つまり独立した実行可能ファイルの名前が必要です。 cdは、シェルの組み込みコマンドである必要があり、実行可能ファイルである場合は、そのディレクトリに変更できることと、自動マウント可能なディレクトリの場合のような潜在的な副作用を確認する以外は効果がありません。これが、2番目の例が機能しない理由です。

23
mouviciel

すでに与えられている正しい答えに加えて:bashを実行してcdのような「コマンド」が何であるかを知りたい場合を使用できますタイプ

$ type cd
cd is a Shell builtin

またはなぜそうではない:

$ type time
time is a Shell keyword

一方、たとえばgnu時間は通常、すでにお気に入りのディストリビューションに含まれています。

$ 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.
4
3molo

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

echo test | cd /

したがって、シェルがこのコマンドから戻った後は、/フォルダーにはいません。

4
Mark Rejhon

他の人が言ったように、cdはシェルの組み込みコマンドであり、外部プログラムではないため、パイプラインで接続できる標準入力がないため、機能しません。

しかし、それが機能したとしても、それはあなたが望むことはしません:パイプは新しいプロセスを生成し、最初のコマンドの標準出力を2番目のコマンドの標準入力にリダイレクトします。したがって、新しいプロセスだけが現在の動作を変更しますディレクトリ;これは、最初のプロセスにはまったく影響しません。

0
Massimo