Bashはパラメータ拡張の文字列置換部分で引用をどのように処理しますか?

Bashはパラメータ拡張の文字列置換部分で引用をどのように処理しますか?

一貫したロジックがありますか?

some-command "${somevariable//some pattern/'how does this get parsed?'}"

以下にいくつかの結論と独創的なテストを「回答」として投稿しましたが、決して完全な答えではありません。 Bashのマニュアルページにはこのトピックが記載されていないようです。

ベストアンサー1

コメントで説明したように、これはBashバージョン間で変更されたようです。これが適切な変化だと思いますbash-4.3-alpha変更ログ):

ZZ。パターン置換語拡張を使用すると、bash は文字列内の引用符をエスケープ文字として機能させることができるようになり、引用符を削除して置換文字列を実行します。これは以前のバージョンと互換性がないため、bash互換モードを4.2に設定して無効にすることができます。

しかもshopt -s compat42オンラインマニュアル):

compat42
設定すると、bash はパターン置換単語拡張で置換文字列を処理するために引用符の削除を使用しません。

一重引用符で引用する例:

$ s=abc\'def; echo "'${s//\'/\'\\\'\'}'"
'abc'\''def'

$ shopt -s compat42
$ s=abc\'def; echo "'${s//\'/\'\\\'\'}'"
'abc\'\\'\'def'

$ bash --version | head -1
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)

回避策:代替文字列を変数に入れてからいいえ置換に引用符を使用します。

$ shopt -s compat42
$ qq="'\''"; s=abc\'def; echo "'${s//\'/$qq}'";
'abc'\''def'
$ qq="'\''"; s=abc\'def; echo "'${s//\'/"$qq"}'";
'abc"'\''"def'

興味深いことに、拡張が行われると引用しない、すべてのバージョンで置き換えられた後、引用符が削除されます。それがs=abc; echo ${s/b/""}版画だac。これは間違いなくs='a""c' ; echo ${s%x}出力などの他の拡張では発生しませんa""c

おすすめ記事