В Bourne-подобных оболочках оператор if
обычно выглядит так
if
command-list1
then
command-list2
else
command-list3
fi
Пункт then
выполняется, если код выхода из command-list1
списка команд равен нулю. Если код выхода ненулевой, то выполняется условие else
. command-list1
может быть
простым или сложным. Например, это может быть последовательность одного или нескольких конвейеров, разделенных одним из операторов ;
, &
, &&
, ||
или newline. Условия if
, показанные ниже, являются лишь частными случаями command-list1
:
if [ condition ]
[
- это другое название традиционной команды test
. [
/ test
- это стандартная утилита POSIX. Во всех оболочках POSIX она встроена (хотя POSIX² этого не требует). Команда test
устанавливает код выхода, а оператор if
действует соответствующим образом. Типичные тесты: существует ли файл или одно число равно другому.
if [[ условие ]]
Это новая модернизированная вариация на тему test
¹ из ksh, которую также поддерживают bash, zsh, yash, busybox sh. Эта конструкция [[ ... ]]
также задает код выхода, и оператор if
действует соответствующим образом. Среди его расширенных возможностей - проверка соответствия строки шаблону подстановочного знака (не в busybox sh).
if ((condition))
Еще одно расширение ksh, которое также поддерживают bash и zsh. Оно выполняет арифметические действия. В результате арифметики устанавливается код выхода, и оператор if
действует соответствующим образом. Он возвращает код выхода, равный нулю (true), если результат арифметического вычисления ненулевой. Как и [[...]]
, эта форма не является POSIX и поэтому не переносима.
if (command)
Это запускает команду во вложенной оболочке. Когда команда завершается, она устанавливает код выхода, и оператор if
действует соответствующим образом.
Типичная причина использования подобной подоболочки - ограничение побочных эффектов команды
, если команда
требует назначения переменных или других изменений в окружении оболочки. Такие изменения не сохраняются после завершения подпрограммы.
if command
команда выполняется, и оператор if
действует в соответствии с ее кодом выхода.
¹ хотя это не совсем команда, а специальная конструкция оболочки, имеющая свой собственный синтаксис, отличный от синтаксиса обычной команды, и значительно отличающаяся в разных реализациях оболочки
² POSIX требует, чтобы в системе были автономные утилиты test
и [
, хотя в случае [
было известно, что в некоторых дистрибутивах Linux они отсутствуют.
При полной или настольной установке Solaris 11 доступны три реализации awk
, плюс несколько вариантов:
/usr/bin/awk pkg:/system/core-os@0.5.11-0.175.3.1.0.2.0 /usr/bin/nawk pkg:/system/core-os@0.5.11-0.175.3.1.0.2.0 /usr/bin/oawk pkg:/system/core-os@0.5.11-0.175.3.1.0.2.0 /usr/gnu/bin/awk pkg:/text/gawk@3.1.8-0.175.3.0.0.30.0 /usr/bin/gawk pkg:/text/gawk@3.1.8-0.175.3.0.0.30.0 /usr/bin/igawk pkg:/text/gawk@3.1.8-0.175.3.0.0.30.0 /usr/bin/pgawk pkg:/text/gawk@3.1.8-0.175.3.0.0.30.0 /usr/xpg4/bin/awk pkg:/system/xopen/xcu4@0.5.11-0.175.3.0.0.30.0
Все они "стандартно совместимы", хотя и соответствуют разным стандартам.
/usr/bin/awk
соответствует устаревшей реализации UNIX awk
, выпущенной в 1977 году. Он сохраняется первым в системном PATH по умолчанию, чтобы не нарушать существующие скрипты, поскольку последующие релизы awk
нарушают совместимость. oawk
- синоним awk
/usr/bin/nawk
- "новая" версия awk
, впервые выпущенная в SVR3.1 в 1986 году. Awk
Стандарт POSIX был основан на этой реализации. /usr/xpg4/bin/awk
почти идентична первой, но формально проверяется тестами на соответствие POSIX.
/usr/gnu/bin/awk
, также /usr/bin/gawk
- это GNU-вариант awk
. Он стремится соответствовать большинству или всем стандартам POSIX, когда переменная окружения POSIXLY_CORRECT
установлена в окружении или когда вызывается с опцией -W posix
, но в остальном добавляет множество специфических собственных расширений. igawk
и pgawk
сами являются расширениями gawk
, первый поддерживает включаемые файлы, а второй - профилирование.
См. также главу GNU awk
history, в которой содержится много полезной информации.
Только пакеты core-os
гарантированно присутствуют в обычной установке Solaris 11, поэтому там есть только oawk/awk
и nawk
. В частности, когда вы создаете новую не глобальную зону, она по умолчанию содержит solaris-small-server
групповой пакет, поэтому ни xpg4
, ни gnu
awk
двоичные файлы недоступны. Это сделано специально. Группа solaris-small-server
- это минимальная начальная точка, в которую вы добавляете пакеты, необходимые для нормальной работы ваших приложений. Это более безопасно и эффективно, чем предыдущий способ (Solaris 10), когда все, установленное в глобальной зоне, устанавливалось и в неглобальной, так что вам приходилось удалять неиспользуемые пакеты, когда вы хотели свернуть зону.
Чтобы получить поддержку POSIX awk
портативным способом в такой установке "маленького сервера", вам нужно установить пакет xcu4
и установить PATH в соответствие с POSIX:
pkg install xcu4
PATH=$(getconf PATH):$PATH
Если по какой-то причине вы не хотите устанавливать этот пакет, обходным решением будет использование "пользовательского" PATH
, содержащего nawk
как awk
, например. например:
mkdir -p /opt/posix/bin
cp /usr/bin/nawk /opt/posix/bin/awk
PATH=/opt/posix/bin:$PATH
В качестве альтернативы вы можете установить GNU awk
и установить PATH
, чтобы получить его первым:
pkg install gawk
PATH=/usr/gnu/bin:$PATH
Обратите внимание, что это не характерно для Solaris 11. подобная группировка пакетов уже существовала в Solaris 10 и более ранних версиях, и POSIX-совместимые утилиты устанавливались только в метакластерах "Конечный пользователь", "Разработчик" и "Полная установка". Если бы система или зона была установлена в метакластере "Core" или "Networking support", это привело бы к той же самой проблеме отсутствия xpg4
.
Заметим также, что отсутствие /usr/xpg4/bin/awk
в системе Solaris 11 не является нарушением соответствия POSIX. В подавляющем большинстве тестов, проводимых Oracle и ISV, включая программу сертификации Open Group, используются только полные установки Solaris. Уменьшенные установки поддерживаются, но не квалифицируются.
Если вы распространяете shell-сценарии (или приложения, встраивающие shell-сценарии/вызывающие shell-команды) для Solaris 11, вам просто нужно определить /system/xopen/xcu4
как зависимость в их IPS пакете, и программа установки автоматически сделает все необходимое для правильной работы сценария:
depend fmri=pkg:/system/xopen/xcu4 type=require
См. https://docs.oracle.com/cd/E53394_01/html/E54820/dependtypes.html