Być może oczywiste zastrzeżenie: sprawdza poprawność składni, ale nie sprawdza, czy skrypt bash próbuje wykonać polecenie, które nie jest na twojej ścieżce, jak ech hellozamiast echo hello.
Na stronie podręcznika bash, w sekcji „KOMENDY / KOMPLETY BUDOWLANYCH SHELL”, -n jest udokumentowane, a na początku strony podręcznika bash interpretuje wszystkie opcje setjednoznakowe.
ephemient
24
dodać do (dla mnie) nie oczywistym zastrzeżeniem, że również nie złapie błędu spowodowanego przez brak miejsca if ["$var" == "string" ], zamiastif [ "$var" == "string" ]
Brynjar
11
@Brynjar To dlatego, że to tylko sprawdzanie składni. Otwarty nawias nie jest składnią, to nazwa funkcji do uruchomienia. type [mówi „[jest wbudowaną powłoką”. Ostatecznie deleguje się do testprogramu, ale oczekuje również zamknięcia. Więc to jest if test"$var", co nie jest tym, co miał na myśli autor, ale jest poprawne składniowo (powiedzmy, że $ var ma wartość „a”, wtedy zobaczymy „bash: testa: komenda nie znaleziona”). Chodzi o to, że składniowo nie brakuje miejsca.
Joshua Cheek
2
@JoshuaCheek: Wbudowany [jest wywoływany tylko w tym przypadku, jeśli $varzdarzy się rozwinąć do pustego ciągu . Jeśli $varrozwija się do niepustego łańcucha, [jest łączony z tym łańcuchem i interpretowany przez Bash jako nazwa polecenia (nie nazwa funkcji ), i tak, jest poprawny pod względem składniowym , ale, jak sam twierdzisz, oczywiście nie jest to intencją. Jeśli użyjesz [[zamiast tego [, mimo że [[jest słowem kluczowym powłoki (a nie wbudowanym), otrzymasz ten sam wynik, ponieważ niezamierzone połączenie ciągów znaków nadal zastępuje rozpoznawanie słowa kluczowego.
mklement0
2
@JoshuaCheek: Bash nadal sprawdza składnię - zaznacza tutaj: sprawdza składnię wywołania prostych poleceń : ["$var"jest składniowo poprawnym wyrażeniem nazwa-polecenia ; podobnie, tokeny ==i "$string"są poprawnymi argumentami polecenia . (Ogólnie, wbudowane [jest analizowana z poleceń składni, podczas gdy [[- w powłoce hasła - jest analizowana w inny sposób). Określenie wbudowane powłoki [jest nie przekazywać do „ testprogramu” (użyteczności zewnętrzna): bash, dash, ksh, zshmają wbudowany wersje zarówno [itesti nie nazywają swoich odpowiedników narzędziami zewnętrznymi.
mklement0
127
Czas zmienia wszystko. Oto strona internetowa, która zapewnia sprawdzanie składni online skryptu powłoki.
Odkryłem, że jest to bardzo potężne narzędzie do wykrywania typowych błędów.
Informacje o ShellCheck
ShellCheck to narzędzie do analizy statycznej i usuwania kłaczków dla skryptów sh / bash. Koncentruje się głównie na obsłudze typowych błędów składniowych i pułapek dla początkujących i średniozaawansowanych, w których powłoka po prostu wyświetla tajemniczy komunikat o błędzie lub dziwne zachowanie, ale raportuje także o kilku bardziej zaawansowanych problemach, w których przypadki narożne mogą powodować opóźnione awarie.
Świetna wskazówka; na OSX można teraz również zainstalować shellcheck.net CLI, shellcheckpoprzez Homebrew : brew install shellcheck.
mklement0
3
Także na debianie i przyjaciołach:apt-get install shellcheck
ten drugi facet
W przypadku zaufanego systemu Ubuntu pakiet ten należy zainstalować z trusty-backports.
Peterino,
Jak wspomniano powyżej, potrzebna jest niezawodna zależność i można ją zainstalować jak poniżej w Ubuntu 14.04: sudo apt-get -f install, a następnie: sudo sudo apt-get install shellcheck
zhihong
Jest to bardzo przydatne, ale nie używa parsera Basha, ale jego własny. W większości przypadków jest to wystarczająco dobre i może identyfikować zarówno parsowanie, jak i inne problemy, ale istnieje co najmniej jeden przypadek krawędzi (i prawdopodobnie inne, których nie widziałem), w którym nie analizuje się w ten sam sposób.
Daniel H
38
Włączam również opcję „u” w każdym skrypcie bash, który piszę, aby wykonać dodatkowe sprawdzenie:
set-u
Spowoduje to zgłoszenie użycia niezainicjowanych zmiennych, jak w poniższym skrypcie „check_init.sh”
#!/bin/shset-u
message=hello
echo $mesage
Uruchamianie skryptu:
$ check_init.sh
Zgłasza następujące:
./check_init.sh[4]: mesage: Parametr nie został ustawiony.
ustawiam te flagi zawsze w moich skryptach bash, jeśli mi się to uda, dobrze jest przejść „set -o errexit” „set -o rzeczownik” „set -o pipefail”
μολὼν.λαβέ
+1, set -uchociaż tak naprawdę nie odpowiada na pytanie, ponieważ musisz uruchomić skrypt, aby otrzymać komunikat o błędzie. Nawet nie bash -n check_init.shpokazuje tego ostrzeżenia
rubo77
23
sh -n script-name
Uruchom to. Jeśli skrypt zawiera błędy składniowe, zwraca ten sam komunikat o błędzie. Jeśli nie ma żadnych błędów, wychodzi bez podania żadnej wiadomości. Możesz natychmiast sprawdzić za pomocą echo $?, który zwróci 0potwierdzenie bez powodzenia.
To działało dla mnie dobrze. Pracowałem na Linux OS, Bash Shell.
Chociaż nie jest to dokładnie związane ze sprawdzaniem składni bash - użycie zestawu -x i set + x do debugowania pełnego skryptu lub jego części jest całkiem przydatne
GuruM
Dzięki, że nie wiedziałem, że nie wiedziałem o -n, ale chciałem @GuruM> sh -x test.sh, ponieważ wyświetla on wygenerowane wyjście skryptu
zzapper
1
Tak. Zapomniałem wspomnieć, że możesz wykonać następujące czynności W wierszu poleceń: 1) bash -x test.sh # uruchamia cały skrypt w „trybie debugowania” 2) ustaw + x; bash test.sh; ustaw -x # ustaw tryb debugowania wł. / wył. przed / po uruchomieniu skryptu W skrypcie: a) #! / bin / bash -x #add „tryb debugowania” u góry skryptu b) ustaw + x; kod; ustaw -x #add „tryb debugowania” dla dowolnej sekcji skryptu
GuruM
sh -nprawdopodobnie nie sprawdzi, czy skrypt jest prawidłowym skryptem Bash. Może dawać fałszywe negatywy. shto wariant powłoki Bourne'a, który zwykle nie jest Bash. Na przykład w Ubuntu Linux realpath -e $(command -v sh)daje / bin / dash
jarno
4
Właściwie sprawdzam wszystkie skrypty bash w bieżącym katalogu pod kątem błędów składniowych BEZ uruchamiania ich za pomocą findnarzędzia:
Przykład:
find . -name '*.sh' -exec bash -n {} \;
Jeśli chcesz go użyć do pojedynczego pliku, po prostu edytuj symbol wieloznaczny z nazwą pliku.
Ale to nie zadziała, jeśli twoje pliki nie kończą się .shskryptami Bash lub innym rozszerzeniem związanym z tym skryptem, co ma miejsce, jeśli generujesz skrypty za pomocą jakiegoś narzędzia szablonowego, takiego jak ERB (wtedy się kończą .erb). Głosuj na youtrack.jetbrains.com/issue/IDEA-79574, jeśli chcesz to naprawić!
Greg Dubicki
1
Jeśli potrzebujesz w zmiennej ważności wszystkich plików w katalogu (git pre-commit hook, build lint script), możesz złapać wyjście stderr komend „sh -n” lub „bash -n” (zobacz inne odpowiedzi) w zmiennej i na tej podstawie mieć „if / else”
bashErrLines=$(find bin/-type f -name '*.sh'-exec sh -n {} \; 2>&1>/dev/null)if["$bashErrLines"!=""];then# at least one sh file in the bin dir has a syntax error
echo $bashErrLines;
exit;fi
Odpowiedzi:
Być może oczywiste zastrzeżenie: sprawdza poprawność składni, ale nie sprawdza, czy skrypt bash próbuje wykonać polecenie, które nie jest na twojej ścieżce, jak
ech hello
zamiastecho hello
.źródło
set
jednoznakowe.if ["$var" == "string" ]
, zamiastif [ "$var" == "string" ]
type [
mówi „[jest wbudowaną powłoką”. Ostatecznie deleguje się dotest
programu, ale oczekuje również zamknięcia. Więc to jestif test"$var"
, co nie jest tym, co miał na myśli autor, ale jest poprawne składniowo (powiedzmy, że $ var ma wartość „a”, wtedy zobaczymy „bash: testa: komenda nie znaleziona”). Chodzi o to, że składniowo nie brakuje miejsca.[
jest wywoływany tylko w tym przypadku, jeśli$var
zdarzy się rozwinąć do pustego ciągu . Jeśli$var
rozwija się do niepustego łańcucha,[
jest łączony z tym łańcuchem i interpretowany przez Bash jako nazwa polecenia (nie nazwa funkcji ), i tak, jest poprawny pod względem składniowym , ale, jak sam twierdzisz, oczywiście nie jest to intencją. Jeśli użyjesz[[
zamiast tego[
, mimo że[[
jest słowem kluczowym powłoki (a nie wbudowanym), otrzymasz ten sam wynik, ponieważ niezamierzone połączenie ciągów znaków nadal zastępuje rozpoznawanie słowa kluczowego.["$var"
jest składniowo poprawnym wyrażeniem nazwa-polecenia ; podobnie, tokeny==
i"$string"
są poprawnymi argumentami polecenia . (Ogólnie, wbudowane[
jest analizowana z poleceń składni, podczas gdy[[
- w powłoce hasła - jest analizowana w inny sposób). Określenie wbudowane powłoki[
jest nie przekazywać do „test
programu” (użyteczności zewnętrzna):bash
,dash
,ksh
,zsh
mają wbudowany wersje zarówno[
itest
i nie nazywają swoich odpowiedników narzędziami zewnętrznymi.Czas zmienia wszystko. Oto strona internetowa, która zapewnia sprawdzanie składni online skryptu powłoki.
Odkryłem, że jest to bardzo potężne narzędzie do wykrywania typowych błędów.
Informacje o ShellCheck
ShellCheck to narzędzie do analizy statycznej i usuwania kłaczków dla skryptów sh / bash. Koncentruje się głównie na obsłudze typowych błędów składniowych i pułapek dla początkujących i średniozaawansowanych, w których powłoka po prostu wyświetla tajemniczy komunikat o błędzie lub dziwne zachowanie, ale raportuje także o kilku bardziej zaawansowanych problemach, w których przypadki narożne mogą powodować opóźnione awarie.
Kod źródłowy Haskell jest dostępny na GitHub!
źródło
shellcheck
poprzez Homebrew :brew install shellcheck
.apt-get install shellcheck
trusty-backports
.Włączam również opcję „u” w każdym skrypcie bash, który piszę, aby wykonać dodatkowe sprawdzenie:
Spowoduje to zgłoszenie użycia niezainicjowanych zmiennych, jak w poniższym skrypcie „check_init.sh”
Uruchamianie skryptu:
Zgłasza następujące:
Bardzo przydatne do łapania literówek
źródło
set -u
chociaż tak naprawdę nie odpowiada na pytanie, ponieważ musisz uruchomić skrypt, aby otrzymać komunikat o błędzie. Nawet niebash -n check_init.sh
pokazuje tego ostrzeżeniaUruchom to. Jeśli skrypt zawiera błędy składniowe, zwraca ten sam komunikat o błędzie. Jeśli nie ma żadnych błędów, wychodzi bez podania żadnej wiadomości. Możesz natychmiast sprawdzić za pomocą
echo $?
, który zwróci0
potwierdzenie bez powodzenia.To działało dla mnie dobrze. Pracowałem na Linux OS, Bash Shell.
źródło
sh -n
prawdopodobnie nie sprawdzi, czy skrypt jest prawidłowym skryptem Bash. Może dawać fałszywe negatywy.sh
to wariant powłoki Bourne'a, który zwykle nie jest Bash. Na przykład w Ubuntu Linuxrealpath -e $(command -v sh)
daje / bin / dashWłaściwie sprawdzam wszystkie skrypty bash w bieżącym katalogu pod kątem błędów składniowych BEZ uruchamiania ich za pomocą
find
narzędzia:Przykład:
find . -name '*.sh' -exec bash -n {} \;
Jeśli chcesz go użyć do pojedynczego pliku, po prostu edytuj symbol wieloznaczny z nazwą pliku.
źródło
Komenda null [dwukropek] jest również przydatna podczas debugowania, aby zobaczyć wartość zmiennej
źródło
set -x
pokazuje każdą linię przed jej wykonaniemIstnieje wtyczka BashSupport dla IntelliJ IDEA, która sprawdza składnię.
źródło
.sh
skryptami Bash lub innym rozszerzeniem związanym z tym skryptem, co ma miejsce, jeśli generujesz skrypty za pomocą jakiegoś narzędzia szablonowego, takiego jak ERB (wtedy się kończą.erb
). Głosuj na youtrack.jetbrains.com/issue/IDEA-79574, jeśli chcesz to naprawić!Jeśli potrzebujesz w zmiennej ważności wszystkich plików w katalogu (git pre-commit hook, build lint script), możesz złapać wyjście stderr komend „sh -n” lub „bash -n” (zobacz inne odpowiedzi) w zmiennej i na tej podstawie mieć „if / else”
Zmień „sh” na „bash” w zależności od potrzeb
źródło