我刚刚看到一些bash代码,但并不太理解。作为一个新手bash脚本编写者,我不确定正在发生什么。
echo ${0##/*}
echo ${0}
我其实看不出这两个命令的输出有什么不同(都输出脚本名称)。那个#
只是注释吗?还有那个/*
是干嘛用的。如果它是注释,为什么它不会影响到结束的}
大括号呢?
有人能给我解释一下这种语法吗?
我刚刚看到一些bash代码,但并不太理解。作为一个新手bash脚本编写者,我不确定正在发生什么。
echo ${0##/*}
echo ${0}
我其实看不出这两个命令的输出有什么不同(都输出脚本名称)。那个#
只是注释吗?还有那个/*
是干嘛用的。如果它是注释,为什么它不会影响到结束的}
大括号呢?
有人能给我解释一下这种语法吗?
${PARAMETER#PATTERN}
和${PARAMETER##PATTERN}
此形式是从字符串开头尝试匹配并删除所描述的模式。运算符
#
将尝试删除最短的匹配模式,而##
则尝试使用最长的匹配模式。示例字符串(来自一位大人物的引用):
MYSTRING="Be liberal in what you accept, and conservative in what you send"
语法 结果 ${MYSTRING#*in}
Be liberal inwhat you accept, and conservative in what you send.${MYSTRING##*in}
Be liberal in what you accept, and conservative inwhat you send.
${PARAMETER##WORD} Results in removal of the longest matching pattern from the beginning rather than the shortest.
for example
[ian@pinguino ~]$ x="a1 b1 c2 d2"
[ian@pinguino ~]$ echo ${x#*1}
b1 c2 d2
[ian@pinguino ~]$ echo ${x##*1}
c2 d2
[ian@pinguino ~]$ echo ${x%1*}
a1 b
[ian@pinguino ~]$ echo ${x%%1*}
a
[ian@pinguino ~]$ echo ${x/1/3}
a3 b1 c2 d2
[ian@pinguino ~]$ echo ${x//1/3}
a3 b3 c2 d2
[ian@pinguino ~]$ echo ${x//?1/z3}
z3 z3 c2 d2
我认为现有的答案(虽然肯定是准确的)忽略了OP问题的实际重点。
OP询问的内容:
echo ${0##/*}
我猜他们在代码中真正看到的是:
echo ${0##*/}
basename "$0"
但是如果你将它用作变量而不仅仅是将其打印到控制台,那么它可能更加方便(和高效)。(另一方面,基本名称更具可移植性,而参数扩展则是Bashism。)
* 或多或少。 在一些边缘案例(例如以空格开头的文件名),它们输出的内容可能不完全相同。
您是想说 ##/*
还是 ##*/
?
${0##/*}
是一种有点不同寻常的方法 - 它将从 $0
的开头删除前缀 /...
。
这是一种全盘操作:如果 $0
以斜杠开头(例如:/home/bob/myscript.sh
),那么它将删除所有内容并返回一个空字符串,否则(例如:./myscript.sh
)就不会删除任何内容并将返回 $0
的全部内容。
(双重##
表示它应该删除最长匹配;单个#
只会删除首字符,如果它是斜杠。)
我不确定它有多有用。也许它可以用于帮助检测脚本是否从绝对路径调用。
${0##*/}
更为常见 - 它将从 $0
的开头删除前缀 .../
。
例如,如果 $0
是 /home/bob/myscript.sh
,它将返回 myscript.sh
。
再次使用##
表示它应该删除最长的匹配项,因此它将删除所有斜杠(.../.../
)。
(相对于#
,它只会删除第一个斜线,例如:/home/bob/myscript.sh
-> home/bob/myscript.sh
,a/b/myscript.sh
-> b/myscript.sh
。)