sh中的"$ {0%/*}"和"$ {0 ##*/}"

pro*_*eek 5 bash sh

这些是brew命令的摘录.

BREW_FILE_DIRECTORY=$(chdir "${0%/*}" && pwd -P)
export HOMEBREW_BREW_FILE="$BREW_FILE_DIRECTORY/${0##*/}"
Run Code Online (Sandbox Code Playgroud)

做什么${0%/*}${0##*/}在外壳是什么意思?

fed*_*qui 9

这些是shell 参数扩展:

  • ${var%/*}- 在最后一次出现之后删除所有内容/.
  • ${var##*/}- 删除最后一次出现的所有内容/.

由于您在脚本中,$0因此请参阅脚本本身的名称.

总之,这将返回您正在运行的脚本的路径或名称.所以你有点做:

BREW_FILE_DIRECTORY=$(chdir <path_of_script> && pwd -P)
export HOMEBREW_BREW_FILE="$BREW_FILE_DIRECTORY/<script_name>"
Run Code Online (Sandbox Code Playgroud)

测试

$ r="hello/how/are/you"
$ echo ${r%/*}
hello/how/are
$ echo ${r##*/}
you
Run Code Online (Sandbox Code Playgroud)

从上面提到的链接(编辑版本,使它们更短):

$ {参数##字}

这个词被扩展为产生一个模式,就像文件名扩展一样.如果模式匹配参数的扩展值的开头,则扩展的结果是参数的扩展值,其中删除了最长匹配模式('##'case).如果参数是'@'或'*',则模式删除操作依次应用于每个位置参数,并且扩展是结果列表.

$ {参数%字}

这个词被扩展为产生一个模式,就像文件名扩展一样.如果模式匹配参数展开值的尾部,则展开的结果是删除了最短匹配模式('%'的情况)的参数值.如果参数是'@'或'*',则模式删除操作依次应用于每个位置参数,并且扩展是结果列表.

关于$0它自己,请参阅Bash参考手册 - > 6.1调用bash:

如果参数处理后参数仍然存在,并且未提供-c和-s选项,则假定第一个参数是包含shell命令的文件的名称(请参阅Shell脚本).以这种方式调用Bash时,$ 0设置为文件名,位置参数设置为其余参数.Bash从该文件中读取并执行命令,然后退出.


hek*_*mgl 5

这些是字符串操作操作。你可以参考这个文档

${string%substring}  # Deletes shortest match of $substring from back of $string.
${string##substring} # Deletes longest match of $substring from front of $string.
Run Code Online (Sandbox Code Playgroud)

有了这个,我们就可以解释操作符在代码中做了什么。

${0%/*}
Run Code Online (Sandbox Code Playgroud)

假设 $0 是一个文件名,它会给你它所在的目录。它的工作方式与命令相同dirname

${0##*/}
Run Code Online (Sandbox Code Playgroud)

假设 $0 是一个文件名,它将为您提供不带前导路径的文件名。它的工作方式与命令相同basename