“${0%/*}” and “${0##*/}” in sh [duplicate]

大憨熊 提交于 2021-02-15 11:56:15

问题


These are excerpts from a brew command.

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

What do ${0%/*} and ${0##*/} mean in shell?


回答1:


These are shell parameter expansions:

  • ${var%/*} - remove everything after the last occurrence of /.
  • ${var##*/} - remove everything up to the last occurrence of /.

Since you are in a script, $0 refers to the name of the script itself.

All together, this is returning either the path or the name of the script that you are running. So your are kind of doing:

BREW_FILE_DIRECTORY=$(chdir <path_of_script> && pwd -P)
export HOMEBREW_BREW_FILE="$BREW_FILE_DIRECTORY/<script_name>"

Test

$ r="hello/how/are/you"
$ echo ${r%/*}
hello/how/are
$ echo ${r##*/}
you

From the above-mentioned link (edited versions to make them shorter):

${parameter##word}

The word is expanded to produce a pattern just as in filename expansion. If the pattern matches the beginning of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the longest matching pattern (the ‘##’ case) deleted. If parameter is ‘@’ or ‘*’, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.

${parameter%word}

The word is expanded to produce a pattern just as in filename expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the value of parameter with the shortest matching pattern (the ‘%’ case) deleted. If parameter is ‘@’ or ‘*’, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.

And regarding $0 itself, see Bash reference manual -> 6.1 Invoking bash:

If arguments remain after option processing, and neither the -c nor the -s option has been supplied, the first argument is assumed to be the name of a file containing shell commands (see Shell Scripts). When Bash is invoked in this fashion, $0 is set to the name of the file, and the positional parameters are set to the remaining arguments. Bash reads and executes commands from this file, then exits.




回答2:


These are string manipulation operations. You can refer to this document

${string%substring}  # Deletes shortest match of $substring from back of $string.
${string##substring} # Deletes longest match of $substring from front of $string.

Having this, we can explain what the operators are doing in your code.

${0%/*}

Assuming $0 is a file name, it will give you the directory it is located in. It works the same way as the dirname command.

${0##*/}

Assuming $0 is a file name, it will give you the file name without the leading path. It works the same way as the basename command.



来源:https://stackoverflow.com/questions/30980062/0-and-0-in-sh

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!