Расширение параметров Bash не может совпадать с пробелами в таких переменных, как $ * и $ @ - PullRequest
1 голос
/ 09 марта 2019

Используя тире (0.5.10.2), я могу сделать это:

% dash
$ set -- x hello world
$ echo "<${*#x }>"
<hello world>

Это поведение, которое я ожидаю.Содержимое $* (которое x hello world назначено set и разделено пробелами) пропускается через оболочку расширение параметра , чтобы удалить все ведущие x для эха, в результате чего hello world, который я повторяю с окружающими скобками, чтобы продемонстрировать отсутствие окружающего пробела.

Я не могу повторить это в bash (5.0.2 (1) -релиз).Кажется, что пробел недоступен:

% bash
$ set -- x hello world
$ echo "<${*#x }>"
<x hello world>
$ echo "<${@#x }>"     # trying $@ instead of $*
<x hello world>
$ echo "<${*#x}>"      # without the space works but now I have a space
< hello world>
$ echo "<${*#x?}>"     # trying the `?` wildcard for a single character
<x hello world>
$ echo "<${*#x\ }>"    # trying to escape the space
<x hello world>
$ echo "<${*/#x /}>"   # using bash pattern substitution instead
<x hello world>
$ echo "<${*#x$IFS}>"  # trying the input field separator variable
<x hello world>

Есть ли здесь решение?Возможно, каким-то образом можно изменить $* или изменить разделитель выходного поля?

Мой текущий обходной путь - присвоить его временной переменной, но это довольно уродливо.(Мне нужен bash, иначе я бы использовал / bin / sh, что является тире.)

1 Ответ

2 голосов
/ 09 марта 2019

Для массивоподобных операндов строковая операция применяется для каждого элемента перед тем, как они объединяются в пробелах. Поэтому вы не можете применить их к объединяющему пространству.

Вот пример, показывающий это:

$ set -- hello world "hello world with spaces"
$ echo "${*// /<SPACE>}"
hello world hello<SPACE>world<SPACE>with<SPACE>spaces

Пробелы в каждом аргументе заменяются просто отлично, но пробелы между ними, вставленные $*, не затрагиваются.

Обходной путь действительно является временной переменной.

...