Która powłoka wykonuje skrypty, gdy na początku nie ma linii shebang (#! / Path / to / shell)? Zakładam / bin / sh, ale nie mogę potwierdzić.
Jądro odmawia wykonania takich skryptów i powroty ENOEXEC, więc dokładne zachowanie zależy od programu uruchomić taki skrypt z .
- bash 4.2.39 - używa się sam
- busybox-ash 1.20.2 - wykorzystuje się sam
- myślnik 0.5.7 - uruchamia / bin / sh
- fish 1.23.1 - narzeka na ENOEXEC, a następnie obwinia niewłaściwy plik
- AT&T ksh 93u + 2012.08.01 - używa siebie
- mksh R40f - działa / bin / sh
- pdksh 5.2.14 - działa / bin / sh
- sh-heirloom 050706 - wykorzystuje się sam
- tcsh 6.18.01 - działa / bin / sh
- zsh 5.0.0 - działa / bin / sh
- cmd.exe 5.1.2600 - patrzy na ciebie zabawnie.
W glibc działa execv()
lub execve()
po prostu zwraca ENOEXEC. Ale execvp()
ukrywa ten kod błędu i automatycznie wywołuje / bin / sh. (Jest to udokumentowane w exec (3p) .)
Co uważa się za „najlepsze praktyki” pod względem pisania skryptów powłoki, które będą działać na dowolnej platformie? (ok, to jest rodzaj otwartego)
Albo trzymaj się sh
tylko funkcji zdefiniowanych przez POSIX lub po prostu przejdź pełną wersję (która jest powszechnie dostępna) i wspomnij o tym w swoich wymaganiach, jeśli ją rozpowszechniasz.
(Teraz, gdy o tym myślę, Perl - a może Python - byłby jeszcze bardziej przenośny, nie wspominając o lepszej składni).
Zawsze dodawaj linię shebang. Jeśli używasz bash lub zsh, użyj #!/usr/bin/env bash
zamiast twardego kodowania ścieżki powłoki. (Jednak powłoka POSIX z pewnością jest w /bin/sh
, więc pomiń env
w tym przypadku.)
(Niestety, nawet /bin/sh
nie zawsze jest taki sam. Program autoconf GNU musi radzić sobie z wieloma różnymi dziwactwami ).
Czy jest możliwe napisanie skryptu, który próbuje użyć zsh i wraca do bash, jeśli zsh nie jest dostępny? Próbowałem umieścić dwie linie shebang, jak poniżej, ale to tylko błąd ze złym interpretatorem: / bin / zsh: nie ma takiego pliku lub katalogu , jeśli wypróbuję go na maszynie bez zsh.
Może istnieć tylko jedna linia shebang; wszystko po znaku nowej linii nie jest nawet czytane przez jądro i traktowane przez powłoki jako komentarz.
Jest to możliwe , aby napisać skrypt, który działa jako #!/bin/sh
kontrole, które są dostępne, powłoki i tras exec zsh "$0" "$@"
lub exec bash "$0" "$@"
w zależności od wyniku. Jednak składnia używana przez bash i zsh jest tak różna w różnych miejscach, że nie poleciłbym tego robić dla własnego zdrowia psychicznego.
strace -f -e fork,clone,execve
. Niektóre pociski kontynuowały wykonywanie/bin/sh
po awarii; inni sami interpretowali skrypt.readlink /proc/$$/exe
.csh
itcsh
zachowanie zależy od tego, czy skrypt zaczyna się od#
(w którym to przypadku wywołują się zamiast sh, aby zinterpretować skrypt). To sięga czasów, gdy csh obsługiwał komentarze, ale nie powłokę Bourne'a, więc#
była to wskazówka, że był to skrypt csh.1) Bieżąca powłoka, w której działasz. (Bez względu na powłokę)
2) Trzymaj się tego samego typu powłoki (bash / dash / ash / csh / cokolwiek innego) i upewnij się, że twoje „obsługiwane platformy” domyślnie instalują powłokę, której chcesz używać. Spróbuj także użyć powszechnie dostępnych poleceń w systemach. Unikaj opcji specyficznych dla maszyny.
3) Tak naprawdę nie ma logiki „jeśli-to-inaczej”
interpreter directive
. Powinieneś określić powłokę, która powinna istnieć we wszystkich systemach, które chcesz obsługiwać ... tj.#!/bin/bash
Lub określić ogólną,#!/bin/sh
o ile skrypt jest dość ogólny we wszystkich powłokach.źródło