Shell脚本中的$ {0%/ *}有什么作用?


17

很抱歉,如果这是一个愚蠢的问题,但我没有成功搜索它。

第二行到底是做什么的?

#!/bin/sh
cd ${0%/*} || exit 1

我知道第一个是shebang,第二个是尝试更改目录,但令人困惑的是${0%/*}

你能解释一下第二行吗?


2
如Andrea在回答中所述,$ {0%/ *}会在调用脚本名称时转换为以脚本名称为前缀的目录路径。另一种选择是使用内置dirname命令,例如$(dirname $0)
alwayslearning'Jan

@alwayslearning:您使用的dirname是哪种内置的Shell和Shell版本?它当然不是Bash v4.3.11中的版本,它是Ubuntu Trusty中的默认外壳。
David Foerster,

我为此感到歉意,只是检查了dirname它不是内置的shell。
alwayslearning

Answers:


27

${0}是脚本的第一个参数,即脚本名称或路径。如果以方式启动脚本path/to/script.sh,则${0}该字符串将恰好是:path/to/script.sh

%/*零件修改的值${0}。这意味着:取所有字符,直到/后跟一个文件名。在上面的示例中,${0%/*}将为path/to

您可以在外壳上看到它的运行情况:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Sh支持许多其他类型的“参数替换”。例如,这是如何获取文件名而不是路径:

$ echo "${x##*/}"
script.sh

通常,带%%%带后缀,而带###带前缀。您可以阅读有关参数替换的更多信息。


2
这个“ ||出口1”似乎是不必要的:是否必须更改dir $?等于1
约瑟夫Klimuk

2
很高兴提到该结构在手册中记录为“删除匹配的前缀/后缀模式”。记住这的一种好方法是,至少在美国键盘上,#是移位3($的左侧),%是移位5($的右侧)。
chexum

1
@JosefKlimuk:|| exit 1 可能需要,因为cd在出错时可能会以状态2(而不是1)退出。但是,我同意这不是很有用(通常程序不在乎特定的退出状态)。可能这是较大脚本的一部分?
Andrea Corbellini

1
@AndreaCorbellini当然可以。它完全可以使用的唯一唯一方法就是将其作为较大脚本的一部分。仅更改当前目录的脚本无效,因为它仅影响运行该脚本的shell。父进程从未看到它。
hvd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.