Bash パラメータ拡張操作の順序を理解する

Bash パラメータ拡張操作の順序を理解する

Bashのプログラミングブックで同様の例を読んだ。

$ cat indirection 
#!/usr/bin/env bash

set -x
num=1
eval "${!num#*:}"
$ 

スクリプトを実行すると、bash indirection "test:echo blah"スクリプトの最後の行はどのように処理されますか?間接参照が最初に発生すると思っeval "${!num#*:}"たらeval "${1#*:}"?その後、部分文字列は削除されeval "${1#*:}"ますかeval echo blah?それではなぜeval必要なのでしょうか?つまり、${!num#*:}置き換えるとeval "${!num#*:}"同じ結果が得られますか?

答え1

パラメータ拡張の出力は次のとおりです。

$ echo "${1#*:}"
echo blah

はい、そうです。この特別なケースでは、次のようになります。

$ set -- "test:echo blah"
$ eval "${1#*:}"
blah

$ ${1#*:}
blah

同じコマンドを実行してください。しかし、これは必ずしも真実ではありません。

$ "${1#*:}"
bash: echo blah: command not found

実際、シェルメタ文字を含む文字列は、引用符なしで正しく機能しません。

$ set -- "test:echo blah > file"
${1#*:}
blah > file

ただし、リダイレクトは発生しません(ファイルが生成されます)。

$ eval "${1#*:}"

fileというファイルがPWDに生成されます。

関連情報