Bash Shell parameter expansion ${ }

2019-07-14 08:37发布

I am not quite sure how to understand this-

$ var='  '
$ echo "|${var}|"
|  |
$ echo "|${var// /}|"
||

Vs.

$ set -- '' '' ''
$ echo "|${*}|"
|  |
$ echo "|${*// /}|"
|  |

However, when I add this after the above

$ IFS=
$echo "|${*// /}|"
||

What is going wrong in the second set of commands? Is this the expected outcome?

1条回答
Anthone
2楼-- · 2019-07-14 09:01

Example 1

$ var='  '
$ echo "|${var}|"
|  |
$ echo "|${var// /}|"
||

Here you have a simple string consisting of two spaces. When you expand it between two pipe characters, you see two spaces between the pipes. When you use pattern substitution to remove all the spaces from the expansion of the variable, you see the empty string between two pipes.

Example 2

$ set -- '' '' ''

First, you've set each of the first three positional parameters to the empty string. You can observe this by comparing the results of the ${1-foo} with {$4-foo} (which displays the parameter if set, but 'foo' if it is unset).

$ echo ${1-foo}

$ echo ${4-foo}
foo

So we can see that $1 is set, but null, while $4 is unset.

$ echo "|${*}|"
|  |

Next, we see the result of expanding the special parameter $* inside quotation marks, which is a single string consisting of the positional parameters that are set, separated by the first character of the IFS parameter. IFS by default has a space as its first parameter, so what we see is a string that consists of 3 empty strings, each separated by a space, which is just a single string of 2 spaces.

$ echo "|${*// /}|"
|  |

When you apply pattern substitution to $*, the substitution is applied to each positional parameter separately before the resulting parameters are joined using IFS. Since the positional parameters are already empty, removing spaces from them leaves them unchanged. So you get the same result as when you just expanded $* by itself.

Example 3

$ IFS=
$ echo "|${*// /}|"
||

The procedure here is the same as in example 2, with the important difference that now IFS is the null string, rather than its default of ''. Once again, the pattern substitution doesn't really do anything, because there are no spaces to remove from any of the positional parameters. But now, expanding $* results in a string consisting of the positional parameters with no intervening characters. Instead of $1 $2 $3, you get $1$2$3. Since all three are themselves empty strings, the result is the empty string.

查看更多
登录 后发表回答