空の文字列になるパラメーター展開の扱いが異なります


10

更新

で誰かバグbashのメーリングリストがいる確認し、これはバグです。


誰かが興味を持っている場合は、devel branchの最新のコミットで修正を利用できます。


ながら

bash -c 'echo "${1##*""}"' _ bar

空の行を出力し、

bash -c 'echo "${1##*"${1##*}"}"' _ bar

プリントbar

分かりません。${1##*}空の文字列に展開されるため、"${1##*}"そのまま扱う必要があります""が、bashはそうは思わないようです。

他の一般的なsh実装の中で、これについてコンセンサスがあるようです:

$ sh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ash -c 'echo "${1##*"${1##*}"}"' _ bar

$ dash -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh93 -c 'echo "${1##*"${1##*}"}"' _ bar

$ mksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ posh -c 'echo "${1##*"${1##*}"}"' _ bar

$ yash -c 'echo "${1##*"${1##*}"}"' _ bar

$ zsh -c 'echo "${1##*"${1##*}"}"' _ bar

$

bash(の有無にかかわらず--posix)は、それに準拠しない唯一のものです。

$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar

そして、サブストリング処理のものがない場合、動作は期待どおりです:

$ bash -c 'echo "${1##*"${1+}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar ''

$ 

説明書には載っていなかった説明があるのではないでしょうか。これはバグですか、それとも規格の誤解ですか?この動作はどこかに文書化されていますか?


PS:内側のPEの引用符を外さないことが簡単な回避策であることはわかっていますが、これは私の質問の答えにはならず、特殊文字を含む文字列で望ましくない結果になる可能性があります。


GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)空の文字列を出力します
William Pursell '30 / 10/30

GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)「バー」を印刷する
ウィリアムパーセル

@Williamは4.4.20と5.0.11でテストされ、両方とも「bar」を
出力し

これは一般的に拡張の問題のようです。私では4.4.12(3)-releaseecho "${BASH##*"${BASH##*}"}"-> /bin/bash。一方、echo "\${BASH##*"${BASH##*}"}"-> ${BASH##*}およびeval echo "\${BASH##*"${BASH##*}"}"->は空白です。
Jeff Y

回答:


2

これは答えではありません

最初は特別なグロブルールによるものだと思っていましたが、結局bashのバグだと思います。次の4つの例から、これがバグであると私が考える理由がわかるはずです。

$ bash -c 'echo "${1##*${1%%bar}}"' _ foobar        # case 1
bar
$ bash -c 'echo "${1##*${1%%foobar}}"' _ foobar     # case 2

$ bash -c 'echo "${1##*"${1%%bar}"}"' _ foobar      # case 3
bar
$ bash -c 'echo "${1##*"${1%%foobar}"}"' _ foobar   # case 4
foobar

ケース1とケース3は引用符が異なります。ただし、フォームのパラメータ展開では、${parameter##word}パス名展開ルールを使用して処理しますword。だから、*foo*"foo"彼らは特殊なパターン文字を採用しない限り、パス名展開で二重引用符と同じ行動を無視することができます持っています(*?、...)。これは次の例で見られます:

$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar

これが事実である場合、なぜケース2とケース4の動作が異なるのでしょうか?


ケース2とケース4の動作が異なるのはなぜですか?理由もなく、両方${1+}${1+""}膨張し、文字列を空にしないように、彼らは道が扱われていない${1##*}(私の最新の編集を参照)です。したがって、これはバグだと推測できますよね?
oguz ismail

1
@oguzismailまさに!ケース1とケース3が同じように動作する場合、ケース2とケース4も同じように動作するはずです。
kvantour
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.