Как я могу проверить соответствие POSIX сценариев оболочки?

72

Учитывая, что POSIX является наиболее близкой к общему стандарту среди всех единиц, мне интересно знать, существует ли оболочка, которая поддерживает его исключительно. Хотя большинство современных оболочек обеспечивают поддержку POSIX (и без проблем запускают POSIX-совместимые сценарии), они не очень хорошо указывают на несовместимые функции.

Существует ли какая-либо оболочка, которая реализует только POSIX и POSIX таким образом, что она выдаст ошибку для любой несовместимой функции?

РЕДАКТИРОВАТЬ Я хочу уточнить, что я не прошу общих советов по написанию сценариев переносимой оболочки. Соответствующий вопрос, упомянутый в комментариях, уже охватывал это. Я подумал об этом вопросе, когда узнал, что у bashнего есть --posixвозможность, но я обнаружил, что он влияет только на некоторые варианты инициализации, что не совсем то, что я ищу.

rahmu
источник
4
Связанные: Ресурсы для программирования переносимых оболочек
Жиль, "Так, перестань быть злым"
@ Жиль: Может быть, я должен упомянуть, что я сталкивался с этим вопросом, но только один ответ предложил проверить с dash. Я упомянул переносимость как общий контекст для моего вопроса, но это не было его истинным намерением.
Рахму
Конечно, я хотел, чтобы эти два вопроса были связаны, потому что они могут представлять интерес для одних и тех же людей. Они не являются дубликатами в любом случае. Кстати, шикарный тест на соответствие POSIX лучше, чем dash.
Жиль "ТАК - перестань быть злым"
2
busybox довольно близок только к POSIX и POSIX. Одна вещь, которая может сбить вас с толку, - это если вы также установите другие пакеты (например, diffutils), то это может добавить дополнительные функции. Оформить заказ livecd Alpine Linux , который запускает вас в чистой среде busybox. Alpine использует библиотеку musl C, поэтому у вас нет расширений GNU, которые могут добавлять такие функции, как расширенные регулярные выражения.
Майкл Фокс

Ответы:

37

К сожалению, для переносимых сценариев требование 'portable' обычно более строго, чем 'POSIX-совместимое'. То есть написать что-то, что работает в любой оболочке POSIX, не так уж сложно, но заставить его работать в любой реальной оболочке сложнее.

Вы можете начать с установки каждой оболочки в вашем менеджере пакетов, в частности, poshзвуки Debian выглядят так, как вы хотите (Ordinary SHell, совместимый с политикой). Политика Debian - это POSIX с несколькими исключениями ( echo -nуказано, local...).

Помимо этого, тестирование должно охватывать несколько оболочек (особенно / bin / sh) на ряде платформ. Я тестирую на Solaris (/ bin / sh и xpg4 / sh) и BSD. AIX и HP-UX очень совместимы и не вызывают проблем. bash - это маленький собственный мир.

Я бы порекомендовал руководство Autoconf по переносимой оболочке , которая абсолютно великолепна и экономит много времени. Большие куски этого устарели, но это нормально; просто пропустите TruUnix, Ultrix и так далее, если вам все равно!

Николас Уилсон
источник
poshдействительно звучит как то, что я прошу. Я сделаю несколько тестов, как только смогу.
Рахму
1
Я ответил до того, как заметил связанный вопрос! Шикарный выпуск Debian, поэтому он не будет упакован в каждой системе. Кроме того, оболочка не обязательно должна беспокоить больше всего; Несовместимость sed - большая проблема, например.
Николас Уилсон
Я бы не стал портить оболочку Solaris / bin / sh или Bourne (которая не является POSIX). Solaris, как и все современные устройства, имеет оболочку POSIX, просто она не находится в обычном месте (/ usr / xpg4 / bin / sh)
Стефан Шазелас
К сожалению, мы поставляем скрипты, которые должны работать как минимум на каждом / bin / sh. Это не так плохо, как все это ... Я бы предпочел не делать этого, хотя.
Николас Уилсон
2
Причина, по которой я отношусь к / bin / sh как к важной, заключается в том, что она вызывается из shebang во многих сценариях. «/ usr / bin / env sh» вряд ли является улучшением. Если вы собираетесь приложить какие-то усилия к тому, чтобы что-то работало на оболочках, отличных от POSIX, я чувствую, что могу также расставить приоритеты для каждой системы / bin / sh. Скоро какой-нибудь клиент запустит ваш скрипт с оболочкой по умолчанию, что не так уж и необоснованно.
Николас Уилсон
28

Вы можете использовать ShellCheck (GitHub) как линтер для своих скриптов оболочки. Также есть онлайн-версия .

Чтобы обнаружить проблемы совместимости POSIX (например, SC2039 ), строка shebang вашего сценария оболочки должна быть такой #!/bin/sh. Вы также можете перейти --shell=shк shellcheck.

Пример ( test.sh):

#!/bin/sh
if [[ $HOSTNAME == test ]]; then
    echo fail &> foo
fi

Результат ( shellcheck test.sh):

In test.sh line 2:
if [[ $HOSTNAME == test ]]; then
   ^-- SC2039: In POSIX sh, [[ ]] is undefined.
      ^-- SC2039: In POSIX sh, HOSTNAME is undefined.    

In test.sh line 3:
    echo fail &> foo
              ^-- SC2039: In POSIX sh, &> is undefined.
johnLate
источник
1
Все эти годы я никогда не слышал о ShellCheck ... спасибо за ссылку!
Тон ван ден Хевел
Лучший инструмент когда-либо! Особенно, если у вас есть онлайн-версия, это здорово - быстро проверить кусок кода!
Меки
12

Bash будет работать в POSIX-совместимом режиме, если установлена POSIXLY_CORRECTпеременная окружения. Из справочной страницы:

   POSIXLY_CORRECT
          If  this  variable  is  in the environment when bash starts, the
          shell enters posix mode before reading the startup files, as  if
          the  --posix  invocation option had been supplied.  If it is set
          while the shell is running, bash enables posix mode, as  if  the
          command set -o posix had been executed.

Многие другие утилиты GNU также POSIXLY_CORRECTзаслуживают уважения , поэтому, если вы работаете в системе с преимущественно инструментами GNU (например, в большинстве систем Linux), это хорошее начало, если ваша цель - соответствие POSIX.

Джеймс Снерингер
источник
21
Даже в режиме POSIX bash по-прежнему допускает некоторые функции, отличные от POSIX, такие как [[.
Иордания