Aktualizacja
Ktoś w liście dyskusyjnej bug-bash został potwierdzony jest to błąd.
Jeśli ktoś jest zainteresowany, poprawka jest dostępna w najnowszej gałęzi commit to devel .
Podczas
bash -c 'echo "${1##*""}"' _ bar
wypisuje pustą linię,
bash -c 'echo "${1##*"${1##*}"}"' _ bar
odciski bar
.
Nie rozumiem tego ${1##*}
rozwija się do pustego ciągu, więc "${1##*}"
należy go traktować tak, jak ""
jest, ale wydaje się, że bash tak nie uważa.
Wydaje się, że istnieje konsensus w tej sprawie wśród innych popularnych sh
wdrożeń:
$ 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 (z lub bez --posix
) jest jedynym niezgodnym z tym:
$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar
I bez elementów przetwarzających podciąg zachowanie jest zgodne z oczekiwaniami:
$ bash -c 'echo "${1##*"${1+}"}"' _ bar
$ bash -c 'echo "${1##*"${2}"}"' _ bar
$ bash -c 'echo "${1##*"${2}"}"' _ bar ''
$
Naprawdę zastanawiam się, czy jest na to wyjaśnienie, którego nie znalazłem w instrukcji. Czy to błąd, czy błędna interpretacja standardu? Czy to zachowanie jest gdzieś udokumentowane?
PS: Wiem, że szybkim obejściem jest cofnięcie cytowania wewnętrznej PE, ale to nie odpowiada na moje pytanie i może prowadzić do niepożądanych wyników w przypadku ciągów znaków specjalnych.
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
wypisuje pusty ciągGNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
drukuje „bar”4.4.12(3)-release
,echo "${BASH##*"${BASH##*}"}"
->/bin/bash
. Podczas gdyecho "\${BASH##*"${BASH##*}"}"
->${BASH##*}
ieval echo "\${BASH##*"${BASH##*}"}"
-> puste.Odpowiedzi:
Najpierw myślałem, że wynika to ze specjalnych reguł globalnych, ale ostatecznie myślę, że to błąd w bashu. Poniższe cztery przykłady powinny dać ci poczucie, dlaczego uważam, że to błąd:
Przypadek 1 i przypadek 3 różnią się cytatami. Jednak rozszerzenie parametrów formularza
${parameter##word}
korzysta z reguł interpretacji nazw ścieżek do przetworzeniaword
. Tak*foo
i*"foo"
mają identyczne zachowanie jak cudzysłów przy rozwijaniu nazw plików mogą być ignorowane, chyba że objąć specjalne znaki wzorca (*
,?
...). Jest to widoczne w następującym przykładzie:źródło
${1+}
i${1+""}
rozszerza się na pusty ciąg znaków, ale nie są one traktowane droga${1##*}
jest (patrz mój ostatni Edit). Możemy więc wywnioskować, że to błąd, prawda?