Як я можу перевірити відповідність сценаріям оболонки POSIX?


72

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

Чи існує якась оболонка, яка реалізує лише POSIX та POSIX таким чином, щоб вона видала помилку для будь-якої не сумісної функції?

EDIT Хочу уточнити, що я не прошу загальних порад щодо написання портативних скриптів оболонки. Пов'язане питання, згадане в коментарях, вже висвітлювало це. Я подумав над цим питанням, коли виявив, що bashє --posixваріант, але лише щоб виявити, що він впливає лише на деяку поведінку інтіалізації, яка не є точно тим, що я шукаю.



@Gilles: Можливо, я повинен зазначити, що я натрапив на це питання, але лише одна відповідь запропонувала тестувати dash. Я згадував портативність як загальний контекст для свого запитання, але це було не його справжнім наміром.
rahmu

Звичайно, я хотів, щоб два питання були пов'язані, оскільки вони, ймовірно, зацікавлять одних і тих же людей. Вони жодним чином не є дублікатами. До речі, posh - це кращий тест на відповідність POSIX, ніж тире.
Жиль

2
busbox досить близький лише до POSIX та POSIX. Одне, що може вас змусити зрештою, це якщо ви також встановите інші пакунки (наприклад, diffutils), то це може додати функції. Checkout альпійського linux livecd, який запускає вас із чистого середовища для заняття. Alpine використовує бібліотеку musl C, щоб ви не отримували розширення GNU, які можуть додавати такі функції, як розширені регулярні вирази.
Майкл Фокс

Відповіді:


37

На жаль, "портативний" зазвичай є більш високою вимогою, ніж "сумісний з POSIX" для скриптів оболонки. Тобто написати щось, що працює на будь-якій оболонці POSIX, не надто складно, але запустити його на будь-яку оболонку реального світу складніше.

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

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

Я рекомендую посібник з Autoconf до портативної оболонки , яка абсолютно блискуча і економить багато часу. Великі куски цього застарілі, але це нормально; просто пропустіть TruUnix і Ultrix і так далі, якщо вам все одно!


poshнасправді це звучить як те, про що я прошу. Я зроблю кілька тестів, як тільки зможу.
rahmu

1
Я відповів, перш ніж помітити відповідне питання! posh - це річ з debian, тому не буде упакована у кожну систему. Крім того, оболонка не обов'язково повинна турбувати найбільше; наприклад, несумісність sed є великою проблемою.
Ніколас Вілсон

Я б не переймався переносом на Solaris / bin / sh aka оболонку Bourne (що не є POSIX). Solaris, як і всі сучасні уніці, має оболонку POSIX, просто не буває у звичайному місці (/ usr / xpg4 / bin / sh)
Stéphane Chazelas

На жаль, ми доставляємо сценарії, які повинні працювати принаймні кожен / bin / sh. Це не так вже й погано, як усе ... Я б краще не хотів цього робити.
Ніколас Вілсон

2
Причину, яку я вважаю / bin / sh, як важливу, це те, що вона викликається з shebang у стільки сценаріїв. "/ usr / bin / env sh" навряд чи є поліпшенням. Якщо ви збираєтесь докласти будь-яких зусиль, щоб зробити щось робочим на оболонках, що не є POSIX, я думаю, що я можу також визначити пріоритет кожної системи / bin / sh. Незабаром, коли якийсь клієнт запустить ваш сценарій із оболонкою за замовчуванням, це не все нерозумно.
Ніколас Вілсон

28

Ви можете використовувати ShellCheck (GitHub) як лінкер для своїх скриптів оболонки. Також є онлайн-версія .

Для виявлення проблем сумісності POSIX (наприклад, SC2039 ) повинна бути лінія шебанга вашого сценарію оболонки #!/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.

1
Всі ці роки, і я ніколи не чув про ShellCheck ... дякую за посилання!
Тон ван ден Хевель

Найкращий інструмент коли-небудь! Тим більше, що в Інтернеті є його версія - це дивовижно швидко перевірити фрагмент коду!
Mecki

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, такі як [[.
Йорданм
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.