Bash Shebang dla manekinów?

36

Mam kilka skryptów bash, których używam, z których najczęściej korzystam

#!/bin/bash

ale regularnie spotykam takie, które wyglądają

#!/bin/bash -e
#!/bin/bash -x
#!/bin/bash -ex

i tak dalej.

Czy ktoś może wyjaśnić znaczenie i zalety tych opcji shebang i czy dotyczą one innych shebangów?

coneybeare
źródło
Te opcje są specyficzne dla Bash (lub innego tłumacza). Mogą być takie same dla innych powłok (na przykład dash i ksh), ale byłyby inne dla innych interpretatorów, takich jak AWK i Python. Możesz użyć wielu opcji akceptowanych przez tłumacza. Opcje są specyficzne dla interpretera, podczas gdy shebang jest funkcją jądra.
Wstrzymano do odwołania.

Odpowiedzi:

41

Jeśli skrypt /path/to/foozaczyna się od #!/bin/bash, wówczas wykonywanie /path/to/foo arg1 arg2jest równoważne wykonywaniu /bin/bash /path/too/foo arg1 arg2. Jeśli linia shebang jest #!/bin/bash -ex, jest to równoważne z wykonaniem /bin/bash -ex /path/too/foo arg1 arg2. Ta funkcja jest zarządzana przez jądro.

Zauważ, że możesz przenośnie mieć tylko jeden argument w linii shebang: niektóre jednorożce (takie jak Linux) akceptują tylko jeden argument, więc #!/bin/bash -e -xdoprowadziłoby to do tego, że bash otrzymałby pojedynczy pięcioznakowy argument -e -x(błąd składniowy) zamiast dwóch argumentów -ei -x.

W przypadku powłoki Bourne'a shi pochodnych powłok, takich jak POSIX sh, bash, ksh i zsh:

  • -e oznacza, że ​​jeśli dowolne polecenie nie powiedzie się (co wskazuje na zwrócenie niezerowego statusu), skrypt natychmiast się zakończy.
  • -x powoduje, że powłoka drukuje ślad wykonania.

Inne programy mogą zrozumieć te opcje, ale mają różne znaczenia.

Gilles „SO- przestań być zły”
źródło
24

Są to opcje przekazane, aby bashzobaczyć help setwięcej informacji, w tym przypadku:

-x  Print commands and their arguments as they are executed.
-e  Exit immediately if a command exits with a non-zero status.
Cyrus
źródło
3
+1 I -exrobi oba
Nifle
Jest to mylące, ponieważ wyglądają jak opcje wiersza poleceń przekazane do Bash.
Caoilte,
2
@Caoilte: I rzeczywiście są one (z man bash) In addition to the single-character shell options documented in the description of the set builtin command, bash interprets the following options when it is invoked: [...].
cyr
1
arrgh! mrugnij i tęsknisz! :).
Caoilte,
0

Chciałbym tylko wspomnieć o jeszcze lepszej - jak w bardziej przenośnej - alternatywie:

#!/usr/bin/env bash

W powyższym przykładzie envznajduje się bashplik wykonywalny, który nie zawsze jest dostępny /bin/bash. Stare #!/bin/bashskrypty nie działają na przykład w systemie NixOS .

Jeśli używasz env, jak wykazano powyżej, nie może dostarczyć argumentów, takich jak -ena bash(o ile wiem). Ale możesz to zrobić zamiast tego:

#!/usr/bin/env bash
set -e
Simon Alling
źródło
2
Robię to przez cały czas, ale nie powiedziałbym, że jest „bardziej przenośny” - w rzeczywistości ryzyko, że użytkownik uruchomi coś zupełnie innego (niż zakładasz, że system jest dostarczany) jest znacznie większe. Na przykład Ubuntu nadal dostarcza Bash 4, podczas gdy użytkownik może zdecydować się na uruchomienie Bash 5.
slhck
Tak, envużycie nie jest dobre, szczególnie w przypadku skryptów uruchamiających Python, ponieważ po prostu nie wiesz, czy domyślną pythonjest wersja 2 czy 3, a to robi różnicę w przypadku skryptów, które wymagają określonej wersji. Lepiej być wyraźnym niż podstępnym
smac89