За замовчуванням Bash 3 переосмислює shebang / bin / bash з встановленим варивом bash 4


6

Фон

Bash 4 встановлений успішно за допомогою домашнього перекладу та додаткових кроків, необхідних для того, щоб bash 4 був оболонкою за замовчуванням. Багато посібників в мережі з простим google: Посібник з оновлення Example Bash 4 для Mac

  • Розташування Bash 4.x (встановлено за допомогою варіння):/usr/local/bin/bash
  • Місце розташування Bash 3.2 (за замовчуванням OSX): /bin/bash

Проблема

Сценарії Я не можу контролювати / змінювати шебанг , оскільки це вплине на інших користувачів. Якщо я не повинен був змінити вручну, а потім повернути його назад, перш ніж здійснити управління джерелом. Ще один варіант - набрати:bash some_script_with_bin_bash_shebang.shзмусити використовувати щойно дефолтовану оболонку bash 4.

Мені лише коли-небудь потрібно це робити для функцій Bash 4+, що зараз дуже часто.

Питання

Хто-небудь має класну техніку, яка обходиться для отримання псевдоніму Шебанг-баш-контуру так: #!/bin/bashдо нової оболонки bash 4 /usr/local/bin/bash?

Без явної зміни файлу! ^ _ ^ (наприклад, додавання #!/usr/bin/env bash)

Відповіді:


3

Це основна причина в даний час для використання іншого шебангу:

#!/usr/bin/env bash

Це використовуватиме перший баш в PATH, який, швидше за все, буде останньою версією. Оскільки / bin знаходиться у стандартному шляху ( getconf PATH), це витончено повертається для тих, хто не користується bash.


1
Я не думаю, що ти насправді ти читав моє запитання? Я це вже знаю, однак це зовсім не відповідає на моє запитання. Чи потрібно щось зробити, щоб зробити це зрозумілішим? Що я не знаю, це можливість того, що я попросив лол, я розумію, що ви намагаєтеся отримати легкі бали, але я це сказав, не змінюючи файл. Щоб уникнути подібних відповідей.
RST

@RST Я прочитав ваше запитання, але, здається, це проблема XY, і я намагався повернути його на шляху. Для власних сценаріїв, що використовують функцію "Bash 4+", використовуйте env bash, а для сценаріїв, які ви не написали, залиште їх у спокої! Якщо я пишу сценарій для розповсюдження на Mac та використовую / bin / bash, це тому, що я хочу використовувати системний bash, і використання цього шебангу забезпечує це. Якщо я хочу використовувати найновішу доступну версію bash, тоді env bash є вищою, але це не означає, що я повинен змушувати інші сценарії, які я не писав, використовувати те, що я вважаю найкращим.
гр

1
Так само, як деякі користувачі працюють на Linux, а інші на Mac, 99% користувачів Linux мають останні баші протягом багатьох років і включили підхід на базі ENV. По суті, так, найкращим випадком було б піти і змінити їх усіх, це зараз не є можливою. Ось чому я ще раз сказав, не змінюючи файл із інтересу. Я не обов'язково погоджуюся з усім, що ви говорите, але як це є життя.
RST

2

По-перше, ви можете розглянути можливість простої заміни /bin/bashна більш оновлену версію.

По-друге, якщо вам не зручно скасовувати гарантію, роблячи це, і якщо у вас вже є проблеми з існуючим сценарієм, обійдіть його #!рядок, посилаючись на його:

/path/to/bash4/path/to/script.bashargs...

(Ви можете просто використовувати, bashа не повний шлях, якщо ваш $PATHправильний порядок.)

По-третє, якщо цей скрипт є специфічним для пристроїв Apple і повинен мати Bash версії 4, то завжди встановлюйте його явно #!/path/to/bash4, оскільки немає користі встановлювати його ні на що інше. (Це не означає змінити його у вихідному репо, а скоріше вибрати його під час встановлення; див. Нижче.)

По-четверте, подумайте про використання https://gist.github.com/kurahaupo/8130030 - зауважте, що вам потрібна "вихідна" версія сценарію за межами призначеного binкаталогу; наприклад, залиште це у своєму вихідному репо або в `li.

По-п’яте, якщо ви дійсно не хочете торкатися оригінального сценарію, зробіть сценарій заглушки, який викликає його:

#!/bin/sh
exec /path/to/bash4 /path/where/you/stashed/the/original/script "$@"

і встановіть його у відповідний binкаталог.

Джерело проти розгортання

Ваш запит щодо встановлення #!рядка у вихідному репо виказує надзвичайно поширене непорозуміння щодо сценаріїв: ідея про те, що сценарій, просто тому, що це "текст", не повинен "готуватися до використання" в будь-якому сенсі.

Для інших типів програм очевидно: їх потрібно скласти. І якщо вони великі сценарії python або perl, їм потрібен пакет або інсталятор, який буде включати будь-які залежності модуля.

Але навіть навіть скрипту оболонки потрібно, як мінімум, встановити право власності та дозволи та розмістити в binкаталозі. Зазвичай це буде або коли пакет побудований для класу пристроїв, або коли сценарій встановлений на цільовому пристрої. Це також відповідний час для встановлення #!лінії відповідно до середовища розгортання.

Я НЕ рекомендую#!/usr/bin/env bash

Широке поширення реклами #!/usr/bin/envтрохи послаблює загальну безпеку, але таким чином, що, ймовірно, не вкусить людей, які її пишуть, лише користувачів десь вниз. Тому я не рекомендую цього; Дійсно, я прогнозую, що врешті-решт він повернеться і кусає ваших клієнтів, або клієнтів ваших клієнтів, або клієнтів ваших клієнтів ... клієнтів.

Це рекламується як "портативний", але це насправді не так: пристроїв Android та OpenWRT навіть не /usrнабагато менше /usr/bin/env, тому там він зовсім марний. Тож на практиці основними бенефіціарами є користувачі Apple.

Якщо сценарій вимагає нової версії bash, тоді системна версія просто не буде робити, тому безглуздо використовувати її як резервну. Але якщо вам не потрібна остання версія, то встановити її як / bin / bash - це нормально.

Коротше кажучи, якщо ви розгортаєте скрипт в Apple, для якого потрібна версія Bash 4, то вам слід користуватися #!/path/to/bash4, коли ви збираєте сценарій у встановлений пакет, або коли сценарій встановлюється на певному пристрої.

EDIT

Я замінив /usr/local/bin/bashз /path/to/bash4тому , що викликало деяке замішання. Суть не в тому, що /usr/local/bin/bashслід використовувати, а в тому, що повний шлях до bash4, який би він не був, повинен бути чітко вказаний. Якщо ви не знаєте його перед установкою, дивлячись в $PATH тому розумне , що потрібно зробити, але ви хочете запустити короткий тест , як

bash_path=$( type -p bash )
if ! "$bash_path" -c '(( $BASH_VERSION > 4.2 ]]'
then
    echo "ERROR: $bash_path isn't new enough"
    exit 1
fi
{
  printf '#!%s\n' "$bash_path"
  tail -n+2 "$downloaded_file"
} > "$installpath"
chmod a=rx "$installpath"

Однак bash не завжди встановлюється в / usr / local / bin, це залежить від вашої системи упаковки - саме тому env спосіб корисний
Марк

Здається, що заміна / bin / bash явно блокується ОС: sudo mv -vf /bin/bash /bin/bash_oldпризводить доmv: cannot move '/bin/bash' to '/bin/bash_old': Operation not permitted
DrStrangepork
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.