他のところで私は以下のようにcd関数を見ました:
cd()
{
builtin cd "$@"
}
なぜ$@
の代わりに $1
?
私はテストディレクトリ「r st」を作成し、この関数を含むスクリプトを呼び出しました。
$ . cdtest.sh "r st"
だが $ . cdtest.sh r st
を使用したかどうかに失敗しました"$@"
または"$1"
なぜなら、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
に渡され、$1
は最初の引数のみを渡します。
あなたの例では
$ . cdtest.sh "r st"
常に1つの引数を渡すだけで機能しますが、次のようなフラグも渡す場合
$ . cdtest.sh -L "r st"
次に、"$@"
のみが正しく実行され、"$1"
はcd -L
に展開され、ディレクトリが完全に失われます。
しかしながら
$ . cdtest.sh r st
2つのパラメーターr
とst
をcdに渡すと、どちらの場合も失敗します。これは、cdを実行する有効な方法ではありません。パラメータはスペースで区切られ、最初の例のように引用符で囲むか、エスケープ(r\ st
)して、1つの引数として扱う必要があります。
ただし、cdの場合、フラグを渡すことは非常にまれであり、複数のディレクトリを渡すことはできないため、cdに対する"$1"
または"$@"
の実際の使用では違いがわかりません。しかし、他のコマンドについてはwill違いに気づくので、このようなラッパー関数またはスクリプトを作成する場合は常に"$@"
を使用することがベストプラクティスです。
no引数がある場合もあります:
$ 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 ""
||
Bashスクリプトへの引数はスペースで区切られています。 $ 1が最初の引数です。あなたの例では...
例1では、$ 1は文字列「r st」です... 2番目の例では、$ 1は1文字の文字列 'r' ...です。
$ @はすべての引数です。