user183394
user183394

Reputation: 1043

How do I bash shell parameter expand this expression?

I ran into a bash script today, it has the following leading lines:

$ cat -n deploy.sh
 1  #!/bin/bash
 2   
 3  # Usage: ./deploy.sh [host]
 4   
 5  host="${1:[email protected]}"
 6   
 7  # The host key might change when we instantiate a new VM, so
 8  # we remove (-R) the old host key from known_hosts
 9  ssh-keygen -R "${host#*@}" 2> /dev/null
 [...]

Line 5 is easy. Line 9 got me. I "believe" it's a kind of bash parameter expansion, but reading the man page, I am no longer so sure anymore.

Quoting from bash man page:

${parameter#word}
${parameter##word}
          Remove matching prefix pattern.  The word is expanded to produce
          a pattern just as in pathname expansion.  If the pattern matches
          the  beginning of the value of parameter, then the result of the
          expansion is the expanded value of parameter with  the  shortest
          matching  pattern  (the ``#'' case) or the longest matching pat‐
          tern (the ``##'' case) deleted.  If parameter is  @  or  *,  the
          pattern  removal operation is applied to each positional parame‐
          ter in turn, and the expansion is the resultant list.  If param‐
          eter  is  an array variable subscripted with @ or *, the pattern
          removal operation is applied to each  member  of  the  array  in
          turn, and the expansion is the resultant list.

Lets say I just run the script like this

./deploy.sh

without any input parameter, then by line 5, host will be set to [email protected]. Then comes to Line 9, the ${host#*@} comes into play. The # triggers a substitution using the expanded *@. But what does it expands to? It's not a word as used in the man page?

Any tips/hints are appreciated.

Zack

Upvotes: 1

Views: 271

Answers (2)

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84343

In this script, the "*@" is actually a glob pattern, not a special parameter of any kind.

$ host="${1:[email protected]}"; echo "${host#*@}"
example.com

What this construct does is remove the shortest matching prefix of the glob when matched against the value of host. The end result is the domain name, because the glob matches everything in the string up to (and including) the at-sign.

Upvotes: 3

perreal
perreal

Reputation: 97918

It removes the prefix matching the pattern *@ in host (so *@ expands to ubuntu@). For example, [email protected] becomes example.com, i.e., the domain name.

Upvotes: 0

Related Questions