Існує приблизно чотири рівні переносимості для скриптів оболонки (що стосується рядка shebang):
Найбільш портативний: використовуйте #!/bin/sh
шебанг і використовуйте лише базовий синтаксис оболонки, визначений у стандарті POSIX . Це має працювати майже на будь-якій системі POSIX / unix / linux. (Ну, за винятком Solaris 10 і новіших версій, які мали справжню спадщину оболонки Борна, передбачаючи POSIX таким невідповідним, як /bin/sh
.)
Другий за величиною портативний: використовуйте #!/bin/bash
(або #!/usr/bin/env bash
) лінію shebang та дотримуйтесь функцій bash v3. Це буде працювати в будь-якій системі, яка має bash (у очікуваному місці).
Третя найбільш портативна: використовуйте #!/bin/bash
(або #!/usr/bin/env bash
) лінію shebang та використовуйте функції bash v4. Це не вдасться в будь-якій системі, яка має bash v3 (наприклад, macOS, який повинен використовувати її з ліцензійних причин).
Найменше портативний: використовуйте #!/bin/sh
шебанг і використовуйте розширення bash для синтаксису оболонки POSIX. Це не вдасться в будь-якій системі, яка має щось інше, ніж bash for / bin / sh (наприклад, останні версії Ubuntu). Ніколи цього не робіть; це не просто питання сумісності, це просто невірно. На жаль, це багато помилок.
Моя рекомендація: використовуйте найконсервативніший з перших трьох, який забезпечує всі функції оболонки, необхідні для сценарію. Для максимальної портативності використовуйте варіант №1, але, на мій досвід, деякі функції bash (наприклад, масиви) є досить корисними, що я перейду з №2.
Найгірше, що ви можете зробити, це №4, використовуючи неправильний шебанг. Якщо ви не впевнені, які функції є базовими POSIX, а які - розширення bash, або дотримуйтесь bash shebang (тобто варіант №2), або ретельно протестуйте сценарій із дуже базовою оболонкою (наприклад, тире на ваших серверах Ubuntu LTS). У вікі Ubuntu є хороший список башизмів, на які слід стежити .
У питаннях Unix та Linux "Що означає бути сумісним?" Є кілька дуже хороших відомостей про історію та відмінності між оболонками. і питання Stackoverflow "Різниця між sh і bash" .
Також пам’ятайте, що оболонка - не єдине, що відрізняється між різними системами; якщо ви звикли до Linux, ви звикли до команд GNU, у яких багато нестандартних розширень, яких ви не можете знайти в інших системах unix (наприклад, bsd, macOS). На жаль, тут немає простого правила, ви просто повинні знати діапазон варіацій для команд, які ви використовуєте.
Один з найбільш гидких команд з точки зору переносимості є одним із самих основних: echo
. Кожного разу, коли ви використовуєте його з будь-якими параметрами (наприклад, echo -n
або echo -e
), або з будь-якими втечами (зворотними косою рисою) у рядку для друку, різні версії будуть робити різні речі. Кожен раз, коли ви хочете надрукувати рядок без передачі рядка після неї, або зі скачками в рядку, використовуйте printf
натомість (і дізнайтеся, як це працює - це складніше, ніж echo
є). ps
Команда також безлад .
Ще одна загальна річ, яку слід спостерігати, - це нещодавні розширення GNUish до синтаксису командного параметра: старий (стандартний) формат команди полягає в тому, що команді слідують параметри (з одним тире, і кожна опція - одна літера), а потім аргументи команд. Останні (а часто і не портативні) варіанти включають довгі параметри (зазвичай вводяться разом --
), що дозволяють опціям приймати після аргументів і використовувати --
для відокремлення параметрів від аргументів.
#!/bin/sh
і не використовуйте нічого іншого, ніж те, що було надано в оригінальній оболонці.