我刚刚在 bash 中看到了一些我不太明白的代码。作为新手 bash 脚本编写者,我不确定发生了什么。
echo ${0##/*}
echo ${0}
我真的看不出这两个命令的输出有什么不同(打印脚本名称)。这#
只是评论吗?什么是/*
. 如果是评论,为什么它不会干扰}
右括号?
谁能给我一些关于这种语法的见解?
我刚刚在 bash 中看到了一些我不太明白的代码。作为新手 bash 脚本编写者,我不确定发生了什么。
echo ${0##/*}
echo ${0}
我真的看不出这两个命令的输出有什么不同(打印脚本名称)。这#
只是评论吗?什么是/*
. 如果是评论,为什么它不会干扰}
右括号?
谁能给我一些关于这种语法的见解?
请参阅Advanced Bash-Scripting Guide‡ 中有关删除子字符串的部分‡:
${string#substring}
substring
删除 的前面的最短匹配项$string
。${string##substring}
substring
从 的 前面删除最长的匹配项$string
。
子字符串可能包含通配符*
,匹配所有内容。表达式${0##/*}
打印值 of ,$0
除非它以正斜杠开头,在这种情况下它什么也不打印。
‡ 截至 2019 年 3 月 7 日,该指南错误地声称匹配是$substring
,好像substring
是一个变量的名称。它不是:substring
只是一种模式。
${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"
但是如果您将它用作变量而不是仅将其打印到控制台,则可以说更方便(并且更有效)。(OTOH basename 更便携,而参数扩展是一种 bashism。)
* 或多或少。在某些极端情况下(例如以空格开头的文件名),它们不会输出完全相同的内容。