Использование ^ в качестве метасимвола оболочки

19

Я написал небольшой сценарий сегодня, который содержал

grep -q ^local0 /etc/syslog.conf

Во время обзора коллега предложил, чтобы ^local0его цитировали, потому что ^означает «труба» в оболочке Борна. Удивленный этим утверждением, я попытался отследить любую ссылку, в которой упоминалось это. Ничто из того, что я нашел в интернете, не предполагало, что это проблема.

Однако оказывается, что реализация bsh(которая претендует на роль оболочки Bourne) в AIX 7 на самом деле имеет такое поведение:

> bsh
$ ls ^ wc
      23      23     183
$ ls | wc
      23      23     183

Ни одна из других реализаций "оболочки Bourne", которые я пробовал, не ведет себя таким образом (то есть ^вообще не считается метасимволом оболочки). Я пробовал shна CentOS (который действительно bash), и shна FreeBSD (который не Bash). У меня нет много других систем, чтобы попробовать.

Ожидается ли такое поведение? Какие оболочки считают ^метасимволом трубы?

Грег Хьюгилл
источник
1
Я знаю, что ^это отрицательный символ в Zsh, а также в пространстве регулярных выражений. В качестве отдельного комментария обычно рекомендуется использовать одинарные кавычки в выражении grep для переносимости между оболочками.
MKC
В оболочке bourne было много странного поведения, которое мы все еще видим, например, в современном шелл-коде [ x"$foo" = x"bar" ].
Иордания
bshэто не Bourne Shell. Имя злоупотребляет только для оболочки Bourne в AIX. bshэто скорее оболочка, представленная мной в 1984 году в H.Berhold AG для UNOS (первый клон UNIX). Обратите внимание, что AIX не существовал в 1984 году.
Шили

Ответы:

21

Символ ^как синоним |датируется от раковины Томпсона . Они были представлены одновременно в Unix v4 и упоминаются вместе на странице руководства . Свен Масчек упоминает, что ^«вероятно [введено] по соображениям удобства на ранних терминалах только в верхнем регистре», где печатание |было «чем-то вроде боли» .

Оболочка Томпсона давно исчезла, но ее преемник, оболочка Борна, сохранил тот же синтаксис (хотя на его странице руководства только упоминается |).

Оболочки-преемники, такие как ash, bash и ksh, понимают только |как характер трубы. Вы не найдете настоящую оболочку Bourne в вариантах Unix с открытым исходным кодом, так как долгое время не было релиза оболочки Bourne с открытым исходным кодом. (Я думаю, что OpenSolaris включил один, но он не был принят где-либо еще, поскольку к тому времени он был давно устаревшим из-за новых реализаций).

Спецификация Single Unix не упоминается ^как специальный символ, что фактически означает, что оболочка POSIX должна интерпретировать его буквально¹. Я не думаю, что когда-либо существовал полностью POSIX-совместимый вариант оболочки Bourne (только независимые реализации).

^является особенным в zsh, когда опция extendedglobвключена, но не в режиме совместимости с sh. В режиме по умолчанию он во многом отличается от POSIX.

Я ^все равно рекомендую цитировать в регулярном выражении для ясности. Цитируйте регулярное выражение в скрипте независимо от того, какие символы появляются в нем.

¹ За исключением первого символа выражения в скобках в шаблоне с подстановочными знаками, где !это стандартный символ отрицания, но реализации также могут интерпретироваться ^аналогичным образом.

Жиль "ТАК - прекрати быть злым"
источник
Спасибо, что вся тема TUHS 2003 года была поучительной.
Грег Хьюгилл
Для полноты, вы можете упомянуть, что ^это особенный случай, когда это fishоператор перенаправления, rc/ esгде это оператор конкатенации , или csh / tcsh / bash / zsh для раскрытия истории, когда это первый символ командной строки.
Стефан Шазелас
3

Да, OpenSolaris включает в себя исходный код Bourne Shell, но этот источник не является переносимым.

Поддерживаемую и легко переносимую версию источника Bourne Shell можно найти здесь в schily-*.tar.bz2архивах.

Вот соответствующая часть источника в cmd.c:

/* 
* ^ is a relic from the days of UPPER CASE ONLY tty model 33s 
*/ 
if ((t = item(TRUE)) != 0 && (wdval == '^' || wdval == '|')) 

Видите ли, это не связано с конкретной оболочкой (например, оболочкой Томпсона), а с тем фактом, что в 1970-х годах вокруг все еще были только заглавные буквы.

Шили
источник