Расширение параметра, приводящее к пустой строке, обрабатывается по-разному. - PullRequest
9 голосов
/ 30 октября 2019

Обновление

Кто-то в список рассылки bug-bash имеет подтверждено это ошибка.


Если кому-то интересно,исправление доступно в последнем коммите для ветки devel .


Пока

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, но это не отвечает на мой вопрос и может привести к нежелательным результатам со строками, содержащими специальные символы.

1 Ответ

2 голосов
/ 30 октября 2019

Это не ответ

Сначала я подумал, что это из-за специальных глобальных правил, но в конце я думаю, что это ошибкав баш. Следующие четыре примера должны дать вам понять, почему я считаю, что это ошибка:

$ 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 должны вести себя по-разному?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...