在其他地方,我看到了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。