Який переважний Баш-шебанг?


1131

Чи є якийсь Bashшебанг об'єктивно кращий за інші для більшості застосувань?

  • #!/usr/bin/env bash
  • #!/bin/bash
  • #!/bin/sh
  • #!/bin/sh -
  • тощо

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


4
І це /usr/local/bin/bashна OpenBSD.
jww

Відповіді:


1535

Ви повинні використовувати #!/usr/bin/env bashдля портативності : різні * nixes розміщуються bashв різних місцях, а використання /usr/bin/env- це вирішення для запуску першого bashзнайденого на PATH. І shніbash .


9
Дякую. Також схоже на те, що додавання - до кінця $! / Usr / bin / env bash - нічого не зробить, оскільки дозволений * nix у shebang дозволений, і це використовується 'bash'. Це, мабуть, корисно лише для запобігання передачі зловмисних аргументів до сценарію в командному рядку, якщо shebang сценарію є одним з інших без аргументів ( /bin/shтощо).
Куртоз

13
@Ray bashпрацює не у /binвсіх системах.
ptierno

12
Те саме для мене, я щойно додав його до псевдоніма: alias shebang='echo "#!/usr/bin/env bash"'тепер мені просто потрібно відкрити термінал і набрати шебанг, а не їхати сюди.
Ойлекс

19
Ця відповідь оманлива. POSIX не говорить, що envце на /usr/bin/env. Насправді це може бути в /bin/envбудь-якому місці або будь-де, доки воно знаходиться на шляху. Це може бути, /dummy/envякщо /dummyв PATH. Сам Shebang не визначений під POSIX, тому я можу #!stop toasterзапустити USB-кавову машину та бути сумісним з POSIX. Так що #!/usr/bin/env bashне особливо краще, ніж #!/bin/bashце може бути менш портативним залежно.
темна котка

19
Переносність @darkfeline не є абсолютною - математично неможливо зробити будь-який сценарій, який буде робити те саме на кожній платформі. З 2012 по 2018 рік /usr/bin/envіснує на більшості машин, ніж на будь-якій з /bin/bashxor /usr/bin/bash, тому сценарій, який починається з цього рядка, зробить очікуване на якомога більше машин.
l0b0

80

/bin/shЗазвичай це посилання на оболонку системи за замовчуванням, яка часто є, bashале, наприклад, системи Debian мають меншу вагу dash. Так чи інакше, оригінальна оболонка Bourne є sh, тому якщо ваш сценарій використовує деякі bash(2-е покоління, "Bourne Again sh") специфічні особливості ( [[ ]]тести, масиви, різні цукристі речі тощо), то ви повинні бути більш конкретними і використовувати пізніші . Таким чином, у системах, де bash не встановлений, ваш скрипт не працюватиме. Я розумію, що може бути захоплююча трилогія фільмів про цю еволюцію ... але це може бути з чуток.

Також зауважте, що коли викликається як sh, bashпевною мірою поводиться як стандарт POSIX sh (див. Також документи GNU про це).


2
Оболонка Korn для публічного домену (pdksh) за замовчуванням на OpenBSD.
jww

Більшість систем не пов'язуватимуться /bin/shнікуди з тим /usr, що це ускладнить запуск сценаріїв init до /usrмонтажу.
аїй

@aij Я не знаю, чому я помістив "багато чи більшість" туди - я користувач Fedora, де /binі /sbinроками просто за замовчуванням був посилання на, /usr/binі /usr/sbinв цьому контексті /bin/shє посилання bashна фактичне каталог є /usr/bin. Але я виправлю сказане.
делікатне

44

Я рекомендую використовувати:

#!/bin/bash

Це не 100% портативний (деякі системи розміщуються bashв іншому місці /bin), а те, що багато існуючих сценаріїв використовують #!/bin/bashтиск різних операційних систем, щоб зробити /bin/bashхоча б симпосилання на основне місцеположення.

Альтернатива:

#!/usr/bin/env bash

було запропоновано - але немає гарантії, що envкоманда є /usr/bin(і я використовував системи там, де її немає). Крім того, ця форма використовуватиме перший екземпляр bashпоточних користувачів $PATH, що може бути не підходящою версією bash shell.

(Але /usr/bin/envслід працювати на будь-якій досить сучасній системі, або тому, що вона envє, /usr/binабо тому, що система робить щось для того, щоб вона працювала. Системою, про яку я згадував вище, був SunOS 4, який я, ймовірно, не використовував близько 25 років.)

Якщо вам потрібен сценарій для запуску в системі, яка не має /bin/bash, ви можете змінити сценарій, щоб вказати на правильне розташування (це, мабуть, незручно).

Я обговорював компроміси більш глибоко у своїй відповіді на це питання .

Дещо незрозуміле оновлення: одна система, яку я використовую, Termux , шар на зразок настільного Linux, який працює під Android, не має /bin/bash( bashє /data/data/com.termux/files/usr/bin/bash) - але у нього є спеціальна обробка для підтримки #!/bin/bash.


3
Через 2 роки, і це все ще найкраща порада тут. Якщо просте рішення не працює, то вам доведеться поставити під сумнів свої попередні рішення. Прийнята і найбільш прихильна відповідь не помиляється, це просто неправильно :)
Software Engineer

27

Використання рядка shebang для виклику відповідного перекладача не лише для BASH. Ви можете використовувати шебанг для будь-якої мови інтерпретації у вашій системі, наприклад Perl, Python, PHP (CLI) та багатьох інших. До речі, шебанг

#!/bin/sh -

(це також може бути дві тире, тобто --) закінчує параметри bash, все після цього трактуватиметься як назви файлів та аргументи.

Використання envкоманди робить ваш скрипт портативним і дозволяє налаштувати власні середовища для вашого сценарію, отже, слід використовувати портативні сценарії

#!/usr/bin/env bash

Або для будь-якої мови, наприклад для Perl

#!/usr/bin/env perl

Обов’язково перегляньте manсторінки для bash:

man bash

і env:

man env

Примітка. У системах на базі Debian і Debian, як-от Ubuntu, shпов'язано dashне bash. Як використовують усі системні сценарії sh. Це дозволяє bash зростати, а система залишається стабільною, на думку Debian.

Крім того, щоб зберегти виклик * nix, як я ніколи не використовую розширення файлів у скриптах, що викликаються shebang, оскільки ви не можете опустити розширення на виклик на виконуваних файлах, як це можливо в Windows. Команда файлу може ідентифікувати його як сценарій.


4

Це дійсно залежить від того, як ви пишете ваші баш сценарії. Якщо ваш /bin/shфайл посилається на bash, коли bash викликається як sh, деякі функції недоступні .

Якщо ви хочете використовувати особливості bash, не POSIX, використовуйте #!/bin/bash


3
Bash не встановлений на OpenBSD. Якщо ви встановите його через pkg_add, то він знаходиться в ньому /usr/local/bin, що може не бути на шляху.
jww

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