我只是在 bash 中看到了一些我不太懂的代码。作为新手的脚本,我不知道这是怎么回事。
echo ${0##/*} echo ${0}
在这两个命令中,我实际上没有看到输出有什么不同(打印脚本名)。那个 #仅仅是一个评论吗?还有 /*是怎么回事。如果它是一个注释,为什么它不干扰关闭 }括号?
#
/*
}
有人能告诉我一些关于这种语法的见解吗?
Linux 提示: Bash 参数和参数扩展
${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
请参阅 Bash 黑客维基的参数扩展页面上关于 子串删除的章节:
${PARAMETER#PATTERN}和 ${PARAMETER##PATTERN} 这个表单是为了从字符串的开头删除试图匹配它的所描述的模式。操作符 #将尝试删除与模式匹配的最短文本,而 ##尝试删除与模式匹配的最长文本。 示例字符串(只是一个大人物的引用) : MYSTRING="Be liberal in what you accept, and conservative in what you send" 语法 结果 ${MYSTRING#*in} 在你接受的东西上要自由,在你发送的东西上要保守。 ${MYSTRING##*in} 对于你接受的东西要自由,对于你发送的东西要保守。
${PARAMETER#PATTERN}和 ${PARAMETER##PATTERN}
${PARAMETER#PATTERN}
${PARAMETER##PATTERN}
这个表单是为了从字符串的开头删除试图匹配它的所描述的模式。操作符 #将尝试删除与模式匹配的最短文本,而 ##尝试删除与模式匹配的最长文本。
##
示例字符串(只是一个大人物的引用) :
MYSTRING="Be liberal in what you accept, and conservative in what you send"
${MYSTRING#*in}
${MYSTRING##*in}
我不敢相信我正在回答一个青少年的问题,但是我认为现有的答案(当然是准确的)错过了 OP 问题的实际要点。
观察员问道:
echo ${0##/*}
我猜他们在代码中真正看到的是:
echo ${0##*/}
后者本质上意味着“删除最后一个斜杠(如果有的话)之前的所有内容”。因此,这是一种简洁的方法,可以在不使用路径的情况下获得脚本的名称,而不管脚本是如何调用的。等于 *到
basename "$0"
但是,如果您将它作为变量使用,而不是仅仅将它打印到控制台,那么它可能更方便(也更有效率)。(OTOH 基名更具可移植性,而参数扩展则是一种抨击。)
或多或少 * 。还有一些边缘情况(例如以空格开头的文件名) ,它们不会输出完全相同的内容。
你是说 ##/*还是 ##*/?
##/*
##*/
${0##/*}有点不同寻常——它会从 $0的开头去掉前缀 /...。
${0##/*}
$0
/...
这是一个要么全有要么全无的操作: 如果 $0以斜杠开始(例如 /home/bob/myscript.sh) ,那么它将删除所有内容并返回一个空字符串。否则(例如 ./myscript.sh)它将什么也不剥离,并返回整个 $0。
/home/bob/myscript.sh
./myscript.sh
(双 ##表示它应该去掉最长的匹配; 如果是斜杠,单个 #只会去掉第一个字符。)
我不知道这有什么用。也许它可以用来帮助检测是否从绝对路径调用脚本。
${0##*/}更常见-它将从 $0开始。
${0##*/}
例如,如果 $0是 /home/bob/myscript.sh,它将返回 myscript.sh。
myscript.sh
##再次指示它应该去掉最长的匹配项,因此它将去掉所有斜杠(.../.../)。 (与 #不同,#只会去掉第一个斜杠,例如 /home/bob/myscript.sh-> home/bob/myscript.sh,a/b/myscript.sh-> b/myscript.sh)
.../.../
home/bob/myscript.sh
a/b/myscript.sh
b/myscript.sh