回答:
なぜなら、によればbash(1)
、cd
引数を取る
cd [-L|[-P [-e]] [-@]] [dir]
Change the current directory to dir. if dir is not supplied,
...
したがって、ディレクトリは実際には存在しない場合$1
があります。代わりに、-L
または別のフラグなどのオプションになる可能性があります。
これはどれほど悪いですか?
$ cd -L /var/tmp
$ pwd
/var/tmp
$ cd() { builtin cd "$1"; }
$ cd -L /var/tmp
$ pwd
/home/jhqdoe
$
使用する予定の場所ではない場合、事態は非常に悪くなる可能性がありますcd "$1"
…
を使用"$@"
すると、すべての引数がcd
whereに$1
渡されます。asは最初の引数のみを渡します。
あなたの例では
$ . cdtest.sh "r st"
1つの引数のみを渡すように常に動作しますが、次のようなフラグも渡す場合
$ . cdtest.sh -L "r st"
その後、ディレクトリが完全に失われるまで拡張される"$@"
場合にのみ、正しく実行されます。"$1"
cd -L
しかしながら
$ . cdtest.sh r st
2つのパラメーターをcdに渡すため、どちらの場合も失敗しますがr
、st
これはcdを実行する有効な方法ではありません。パラメーターはスペースで区切られます。スペースは、最初の例のように引用符で囲むかr\ st
、1つの引数として扱うためにエスケープする必要があります()。
フラグを渡すことは非常にまれである、あなたはどちらかの現実世界での使用の違いは表示されませんので、あなたが複数のディレクトリに渡すことはできませんが、CDの場合"$1"
または"$@"
CDのために。しかし、他のコマンドのためにあなたがします、常に使用することをお勧めしますので、違いに気付く"$@"
あなたは、このようなラッパー関数やスクリプトを作成する場合。
引数がない場合もあります。
$ cd /tmp; cd; pwd
/home/muru
$ cd_func() { builtin cd "$1"; }
$ cd_func /tmp; cd_func; pwd
/tmp
cd
引数なしでホームディレクトリに変更します。引数なしで、"$@"
何にも展開されませんが"$1"
、空の文字列に展開されます。これらは異なります:
$ args() { for i in "$@"; do echo "|$i|"; done; }
$ args
$ args ""
||
cd
が良いことである理由がついにわかりました。ホームディレクトリに変更する代わりにエラーが発生します。他のいくつかのコマンド、特にrsync
、最初の引数がnullの場合、予期しない動作が発生します(転送のソースに現在のディレクトリが含まれます)。
cd "$*"
また、1つ以上の引数では正しく動作しません。