6 ms·
I write a bash script or two every month so I thought I'm okay. But then came along the very first example: trim_string() { # Usage: trim_string " ex
by croo 7y ago
I write a bash script or two every month so I thought I'm okay. But then came along the very first example:
trim_string() {
# Usage: trim_string " example string "
: "${1#"${1%%[![:space:]]*}"}"
: "${_%"${_##*[![:space:]]}"}"
printf '%s\n' "$_"
}
Ok, so the : is somehow a temporary variable...
Then there is a variable starting at $ and you lost me :D
Can someone break down that line for me? What the hell is going on here?
: "${1#"${1%%[![:space:]]*}"}"
- vghnb 7y ago: is the null command. Kind of like /bin/true. So : followed by anything exists simply to perform expansion on something. If you fully understand what that means, then you will understand this: $_ is simply “whatever the last argument to the previous command expanded to”. So : is the previous command and the ${1… expanded value is now ${_…. Because $_ is used in the expansion of itself, it is the same value, because the command has not yet completed, which would (re) set $_. So use of a thing ($_) in expanding the same thing ($_) is perfectly fine until after that (null) command (:) runs. You see that the final $_ is used standalone. Hope this helps.
- lervag 7y agoI think the idea is that the `:` builtin allows expansion of arguments without actually doing anything else. However, the temporary variable $_ is filled with the content of the expression. That is, after the first : "${1#"${1%%[![:space:]]*}"}" The $_ temporary variable contains the result of removing the leading spaces. In the next line, the spaces at the end are removed from the temporary variable with the "${_%..." syntax. You can test this in your own shell by e.g. doing: : $PATH echo $_
- emmelaich 7y agoI don't like this function very much but here's a few notes... : is a "do nothing" command -- but the line is still evaluated %% means to replace leading chars that match pattern ## means replace trailing chars I don't know why they're using $_; thats the variable containing the interpreter name, i.e. "/bin/bash" [edit - also the name of the previous command!] I can't be bothered analyzing it any further :-)
- vghnb 7y agoAfter the first command, $_ expands to whatever the last argument to the previous command expanded to. In this case the previous command was : and the only argument is by definition the last. This is how you chain things together without clunky temporary variables.
- pxtail 7y agoAnd that's the problem with bash scipting - very quickly it gets very cryptic, difficult to follow and understand without knowing various "clever tricks" and gimmicks. This is all fine and dandy for personal usage but god forbid other developers might need to changes something inside this kind "clever" code.
- ImaCake 7y agoBingo. I am a pretty casual level scripter. My programming is always just a means to an end (usually biology related) and I would much rather write easy to read code that takes 30 secs to run than whatever the pure bash thing in the parent post is.
- adventureadmin 7y agoI feel the code above is clearly a bastardization, which is possible in several languages. Not to discount your point in the many bashisms, but that example is definitely not what's wrong with scripting.