Есть ли какой-нибудь sh-код, который не является синтаксически верным bash-кодом?

31

Есть ли какой-нибудь shкод, который не является синтаксически допустимым кодом bash (не будет ли нарушаться синтаксис)?

Я думаю о перезаписи shс bashопределенными командами.

Александр Миллс
источник
1
Я думаю, под действительным я имел в виду синтаксически действительный, поэтому он не будет нарушать синтаксис
Александр Миллс
2
Разный токенизация? например ((приходит на ум.
кукуруза
1
Для некоторых дистрибутивов /usr/bin/shэто просто символическая ссылка на /usr/bin/bash(я использую CentOS 7.3, и это так). Вы должны проверить, shдействительно ли это bashдля вашего дистрибутива.
Сентиман
1
Несколько лет назад весь мой проект рухнул, когда что-то было «модернизировано» в bash. Мне пришлось изменить все мои линии Шебанга с #!/bin/shна #!/bin/bash. Затем все снова заработало, так что вам действительно нужно быть осторожным. Это могло произойти, когда они начали использовать тире вместо bash для sh.
Джо
1
@ Джо, это противоположность того, о чем просит ОП - у вас был код bash, который был ошибочно помечен как код sh, но не был. ОП спрашивает, могут ли они иметь (фактический, не ошибочно маркированный) код sh, который ломается при запуске с bash, а не может ли он иметь код bash, который ломается при запуске с sh (что очевидно - если расширения bash этого не сделали влияют на доступные языковые функции, они не будут расширениями).
Чарльз Даффи

Ответы:

49

Вот код, который делает что-то другое в POSIX sh и Bash:

hello &> world

Является ли это "недействительным" для вас, я не знаю.

В Bash он перенаправляет как стандартный вывод, так и стандартную ошибку из helloфайла world. В POSIX shон работает helloв фоновом режиме, а затем выполняет пустое перенаправление в него world, обрезая его (т. Е. Он обрабатывается как & >).

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


Что касается статических синтаксических ошибок, в Bash есть зарезервированные слова (например, [[и time), не указанные в POSIX, например, [[ xдопустимый код оболочки POSIX, но синтаксическая ошибка Bash, а также история различных ошибок несовместимости POSIX, которые могут привести к синтаксическим ошибкам, такой как тот из этого вопроса :

x=$(cat <<'EOF'
`
EOF
)
bash: line 2: unexpected EOF while looking for matching ``'
bash: line 5: syntax error: unexpected end of file

«Только синтаксические ошибки» - довольно опасное определение «недействительного» для любых обстоятельств, где это важно, но это так.

Майкл Гомер
источник
3
Обратите внимание, что, хотя в настоящее время расширение скобок делает bash (и zsh, pdksh, ksh93) несовместимыми, POSIX работает над добавлением положения в спецификации, чтобы разрешить расширение скобок{fd}>fileаналогичная проблема), так что bash может снова быть совместимым (расширение скобок) останется неопределенным, но совместимые скрипты должны будут сделать echo "{a,b}", если они хотят {a,b}быть выведены). Смотрите обсуждение, с которого все началось
Стефан Шазелас
2
Также имеет отношение к этому Q & A: austingroupbugs.net/view.php?id=1191#c3983
Стефан
2
Будет ли кто-нибудь, пишущий скрипт в POSIX sh, написать такую ​​команду? ОП переходит от sh к bash, и, насколько я понимаю, кажется, что это будет скорее проблемой в другом направлении?
Богатый
1
@Rich: Конечно. Я не использую системы, где /bin/shесть bash, поэтому, если бы я не знал об этом bashism, то при написании командной строки это могло бы легко произойти. Интервал в ответе делает его маловероятным, но hello&>worldменее надуманным.
R ..
2
Я действительно видел ошибку из-за &>разницы только в прошлом месяце!
Гордон Дэвиссон
16

Краткий пример:

time()(:)

timeв Bash это зарезервированное слово, и ведет себя не так, как в timeпрограмме. Вполне вероятно, что вы нарушите некоторые практические сценарии, пытаясь разобрать результат timeс помощью bash. Но технически это не синтаксическая ошибка. Переопределение timeкак функция будет редким, но вызывает синтаксическую ошибку, как указывает этот вопрос.

Более короткий пример:

a():

Действительно dash, но не POSIX-совместимый.

user23013
источник
3
В целом, любое слово, являющееся нестандартным ключевым словом или встроенной командой в Bash, будет вызывать тот же эффект. В дополнение к time, есть такие вещи , как declare, function, selectи coproc. Хотя некоторые из них явно помечены как неуказанные в стандарте ( ключевые слова и встроенные функции / утилиты ), но я не вижу, например, timeили coprocв списке. И использование --posix, кажется, не помогает.
ilkkachu