在其他地方,我看到了cd功能,如下所示:
cd()
{
builtin cd "$@"
}
为什么建议使用$@
代替$1
?
我创建了一个测试目录“ r st”,并调用了包含此功能的脚本,无论哪种方式都可以工作
$ . cdtest.sh "r st"
但是 $ . cdtest.sh r st
无论我使用"$@"
还是失败"$1"
在其他地方,我看到了cd功能,如下所示:
cd()
{
builtin cd "$@"
}
为什么建议使用$@
代替$1
?
我创建了一个测试目录“ r st”,并调用了包含此功能的脚本,无论哪种方式都可以工作
$ . cdtest.sh "r st"
但是 $ . cdtest.sh r st
无论我使用"$@"
还是失败"$1"
Answers:
因为,根据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"
总是有效,因为您只传递了一个参数,但是如果您也传递了一个标志,例如
$ . cdtest.sh -L "r st"
然后只有"$@"
正确执行"$1"
才能扩展到cd -L
完全丢失目录的位置。
然而
$ . cdtest.sh r st
未能在这两种情况下,你是传递两个参数到CD,r
而st
这是不执行CD的一种有效方式。参数用空格分隔,必须将其引起来(如您的第一个示例)或将其转义(r\ st
),以将其视为一个参数。
但是,在cd的情况下,传递标志非常少见,并且您不能传递多个目录,因此您不会看到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
,对于其他一些命令,空的第一个参数会导致意外的行为(在传输源中包括当前目录)。
cd "$*"
也不能正常使用超过1个arg。