Ресурси для портативного програмування оболонок


65

Які ресурси існують для програмування портативних оболонок? Кінцева відповідь - тестування на всіх цільових платформах, але це рідко практично.

Специфікація POSIX / Single UNIX є початком, але вона не говорить вам ні про те, який рівень підтримки кожної реалізації, а також які існують загальні розширення. Ви можете прочитати документацію кожної реалізації, але це дуже трудомістко і не зовсім точно.

Мені здається, що ідеальним форматом буде якась версія коментованої спільнотою специфікації POSIX, де кожна функція коментується рівнем її підтримки серед різних реалізацій. Чи є таке? Або є інші корисні ресурси?

Наприклад, є сторінки переносу оболонок Sven Mascheck , але мова йде лише про синтаксичні елементи та декілька вбудованих модулів і охоплює лише старі оболонки. Я шукаю більш всебічний ресурс.


2
Примітка. Будь ласка, не відповідайте тут лише, щоб цитувати один конкретний документ про відповідність реалізації. Якщо у вас є одна з таких, відповідна тега wiki була б хорошим місцем.
Жиль

1
Хтось повинен видобути історію редагування для autoconfта Metaconfig(Perl, rn) та зібрати всі трюки та їх пояснювальні коментарі в одному місці.
geekosaur

@geekosaur: Гарна пропозиція. Я ніколи не дивився на внутрішні відомості про autoconf, чи є щось, що можна було б використовувати як керівництво при написанні власних сценаріїв? Якщо так, то це буде гарною відповіддю на моє запитання, навіть якщо воно не є остаточним.
Жиль

5
Я впевнений, що ви обидва могли це легко знайти, але для користі інших людей, які стежать за цією темою, ось посилання на релевантну сторінку з посібника з autoconf: gnu.org/software/hello/manual/autoconf/Portable- Shell.html
Дж. Тейлор

Відповіді:


32

У посібнику з автоконфорації є розділ про програмування портативних оболонок .

Хоча це не спеціально орієнтовано на POSIX, це, мабуть, найповніша колекція того, що робити, а що не робити при спробі написання портативного коду оболонки.


3
Це один з найкращих ресурсів, і він був створений під час написання коду в M4, який повинен був створити код оболонки, який був переносний на якомога більше оболонок.
Тім Пост

6

Окрім dashі poshє bournesh(або bsh) « Оболонка Реліквія Борна» , яка може бути використана для виявлення башизмів .

Проект Heirloom також включає "The Heirloom Toolchest", колекцію понад 100 стандартних утиліт Unix (які можуть послужити відправною точкою для порівняння параметрів командного рядка).


2
Зауважте, що оболонка Bourne не є оболонкою POSIX, а перенесення вашого сценарію до оболонки Bourne означатиме пониження синтаксису вашого сценарію зі стандартної мови POSIX sh до загального знаменника між цим та синтаксисом оболонки Bourne. Не варто думати, якщо ви не хочете бути переносними для стародавніх систем (або Solaris 10 і новіших версій, і у вас немає вибору використовувати стандартний ш, який був у / usr / xpg4 / bin).
Stéphane Chazelas

5

Подібно до цієї відповіді , спробуйте виконати свій скрипт в шикарному виконанні .

Крім того, не забудьте встановити POSIXLY_CORRECTзмінну середовища на істинне, оскільки це призводить до того, що багато програм (не тільки оболонки) більш чітко дотримуються стандартів POSIX.


4

Запис сценаріїв за допомогою тире може стати початком.


3
Тестування з тире - це найменший мінімум, щоб уникнути випадкової залежності від функцій ksh / bash, але я переживаю більше того: знання про недоліки в інших оболонках (наприклад, погана обробка пастки zsh), і перш за все утиліти оболонки (наприклад, findдосі OpenBSD не реалізовано -exec +).
Жиль

FWIW, в OpenBSD findробить в -exec utility {} +даний час.
Кусалаланда

2

Трохи можна спробувати checkbashismsв devscriptsпакеті Debian / Ubuntu .

Вона не є досконалою, але має перевагу бути існуючою відправною точкою. Наприклад, він не бачить класичних збоїв з sed/ findвідносно GNU проти BSD / інших відмінностей.

За замовчуванням він орієнтований на тире Debian +, -pпрапор може бути корисним у вашому випадку.


2

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

Єдина проблема полягає в тому, що /bin/shіноді це не оболонка POSIX. І ви повинні жорстко зашифрувати #!рядок у сценарії, які повинні вести себе як хороші виконувані файли; ви не можете просто попросити користувача вивчити проблему, а потім викликати ваш сценарій як /path/to/posix/shell myscript.

Отже, хитрість полягає у використанні функцій POSIX у вашому сценарії, але змушуйте сценарій автоматично знаходити оболонку POSIX. Один із способів зробити це такий:

#!/bin/sh

# At this point, we may be running under some old shell
# we have to tread carefully.

# note how we use test rather than [ ] syntax and avoid
# depending on test with no argument producing a failure;
# i.e. "test $posix_shell".

if ! test x$posix_shell = x ; then
  # the three possible shell paths are just an example;
  # please extend as necessary.

  for shell in /usr/xpg4/bin/sh /bin/bash /usr/bin/bash ; do
    if test -x $shell ; then
       posix_shell=$shell
    fi
  done
  if test x$posix_shell = x ; then
    echo "no POSIX shell found"
    exit 1
    # or we could avoid bailing here and just fall back on /bin/sh:
    # echo "falling back on /bin/sh: cross your fingers that it works"
    # posix_shell=/bin/sh
  fi
  export posix_shell

  # plain "$@" is broken in ancient shells! 
  # I seem to recall ${@+"$@"}: not sure if that's the right trick.

  exec $posix_shell $0 ${@+"$@"}  # can we count on exec in legacy shells? 
fi

# phew, at this point in the script we have been re-executed and are
# being interpreted by some reasonably modern shell. We can use $(...)
# command substitution, and other features.

Є й інші підходи, такі як генерація коду. Завантажте свої сценарії невеликим сценарієм, який містить тіло файлів скриптів без #! рядок, і додає один.

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

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