Vielleicht eine offensichtliche Einschränkung: Dies bestätigt Syntax aber nicht überprüfen , ob Ihr Bash - Skript versucht , einen Befehl auszuführen , die nicht in Ihrem Pfad ist, wie ech hellostatt echo hello.
In der Manpage von bash wird unter "SHELL BUILTIN COMMANDS / set" -n dokumentiert, und wie zu Beginn der Manpage angegeben, interpretiert bash alle einstelligen Optionen, die setdies tun .
Ephemient
24
Um die (für mich) nicht offensichtliche Einschränkung zu ergänzen, wird es auch keinen Fehler abfangen, der durch ein fehlendes Leerzeichen verursacht wird, if ["$var" == "string" ]anstattif [ "$var" == "string" ]
Brynjar
11
@Brynjar Das liegt daran, dass es sich nur um eine Syntaxprüfung handelt. Die offene Klammer ist keine Syntax, sondern der Name der auszuführenden Funktion. type [sagt "[ist eine eingebaute Shell". Es delegiert letztendlich an das testProgramm, erwartet aber auch eine schließende Klammer. Es ist also so, wie if test"$var"es der Autor nicht gemeint hat, aber syntaktisch gültig ist (sagen wir, $ var hat den Wert "a", dann sehen wir "bash: testa: Befehl nicht gefunden"). Punkt ist, dass syntaktisch kein Platz fehlt.
Joshua Cheek
2
@JoshuaCheek: Builtin [wird in diesem Fall nur aufgerufen, wenn $vares zu einer leeren Zeichenfolge erweitert wird . Wenn es $varzu einer nicht leeren Zeichenfolge erweitert wird, [wird es mit dieser Zeichenfolge verkettet und von Bash als Befehlsname (nicht Funktionsname ) interpretiert. Ja, das ist syntaktisch gültig, aber, wie Sie sagen, offensichtlich nicht die Absicht. Wenn Sie [[anstelle von verwenden [, obwohl [[es sich um ein Shell- Schlüsselwort handelt (und nicht um ein integriertes Schlüsselwort), erhalten Sie dasselbe Ergebnis, da die unbeabsichtigte Verkettung von Zeichenfolgen die Erkennung des Schlüsselworts weiterhin überschreibt.
mklement0
2
@JoshuaCheek: Bash prüft hier immer noch die Syntax : Es überprüft die Aufrufsyntax für einfache Befehle : ["$var"ist syntaktisch ein gültiger Befehlsnamenausdruck ; in ähnlicher Weise, Tokens ==und "$string"gelten Befehl Argumente . ( Im Allgemeinen builtin [mit geparst Befehlssyntax, während [[- als Schalen Schlüsselwort - anders analysiert wird.) Die Schale builtin [ist nicht übertragen auf das „ testProgramm“ (externe Dienstprogramm): bash, dash, ksh, zshhaben alle eingebauten Versionen der beiden [undtestUnd sie nicht nennen ihre Außen-Utility - Pendants.
mklement0
127
Zeit verändert alles. Hier ist eine Website, die eine Online-Syntaxprüfung für Shell-Skripte bietet.
Ich fand es sehr leistungsfähig, häufige Fehler zu erkennen.
Über ShellCheck
ShellCheck ist ein statisches Analyse- und Flusenwerkzeug für Sh / Bash-Skripte. Es konzentriert sich hauptsächlich auf die Behandlung typischer Syntaxfehler und Fallstricke für Anfänger und Fortgeschrittene, bei denen die Shell nur eine kryptische Fehlermeldung oder ein seltsames Verhalten ausgibt, berichtet jedoch auch über einige fortgeschrittenere Probleme, bei denen Eckfälle zu verzögerten Fehlern führen können.
Toller Tipp; Unter OSX können Sie jetzt auch die Shellcheck.net-CLI shellchecküber Homebrew installieren : brew install shellcheck.
mklement0
3
Auch auf Debian & Freunde:apt-get install shellcheck
dieser andere Typ
Für Ubuntu Trusty muss dieses Paket von installiert werden trusty-backports.
Peterino
Wie oben erwähnt, ist eine vertrauenswürdige Abhängigkeit erforderlich, die wie folgt in Ubuntu 14.04 installiert werden kann: sudo apt-get -f install, dann: sudo sudo apt-get install shellcheck
zhihong
Dies ist sehr nützlich, verwendet jedoch nicht den Parser von Bash, sondern einen eigenen. In den meisten Fällen ist dies gut genug und kann sowohl das Parsen als auch andere Probleme identifizieren, aber es gibt mindestens einen Randfall (und wahrscheinlich andere, den ich nicht gesehen habe), bei dem das Parsen nicht ganz auf die gleiche Weise erfolgt.
Daniel H
38
Ich aktiviere auch die Option 'u' für jedes Bash-Skript, das ich schreibe, um zusätzliche Überprüfungen durchzuführen:
set-u
Dadurch wird die Verwendung nicht initialisierter Variablen gemeldet, wie im folgenden Skript 'check_init.sh'.
#!/bin/shset-u
message=hello
echo $mesage
Ausführen des Skripts:
$ check_init.sh
Wird folgendes melden:
./check_init.sh[4]: mesage: Parameter nicht gesetzt.
Ich setze diese Flags immer in meinen Bash-Skripten. Wenn sie diese bestehen, ist es gut, "set -o errexit" "set -o nounset" "set -o pipefail" zu setzen
μολὼν.λαβέ
+1, set -uobwohl dies die Frage nicht wirklich beantwortet, da Sie das Skript ausführen müssen, um die Fehlermeldung zu erhalten. Nicht einmal bash -n check_init.shzeigt diese Warnung
rubo77
23
sh -n script-name
Führen Sie dies aus. Wenn das Skript Syntaxfehler enthält, wird dieselbe Fehlermeldung zurückgegeben. Wenn es keine Fehler gibt, wird es ohne Meldung ausgegeben. Sie können dies sofort überprüfen, indem Sie echo $?die 0Bestätigung ohne Fehler als erfolgreich zurückgeben.
Es hat bei mir gut funktioniert. Ich lief unter Linux OS, Bash Shell.
Obwohl dies nicht genau mit der Überprüfung der Bash-Syntax zusammenhängt - die Verwendung von set -x und set + x zum Debuggen des vollständigen Skripts oder von Abschnitten des Skripts ist sehr nützlich
GuruM
Danke, dass ich nicht wusste, dass ich nichts über das -n wusste, aber ich wollte @GuruM> sh -x test.sh, da dies die generierte Ausgabe des Skripts
anzeigt
1
Ja. Ich habe vergessen zu erwähnen, dass Sie in der Befehlszeile Folgendes tun können: 1) bash -x test.sh #dies führt das gesamte Skript im 'Debug-Modus' aus. 2) set + x; bash test.sh; setze -x # setze den Debug-Modus vor / nach dem Ausführen des Skripts ein / aus Im Skript: a) #! / bin / bash -x #add 'Debug-Modus' oben im Skript b) setze + x; Code; setze -x #add 'Debug-Modus' für jeden Abschnitt des Skripts
GuruM
sh -nwird wahrscheinlich nicht überprüfen, ob das Skript ein gültiges Bash-Skript ist. Es könnte falsche Negative geben. shist eine Bourne-Shell-Variante, die normalerweise nicht Bash ist. Zum Beispiel in Ubuntu Linux realpath -e $(command -v sh)gibt / bin / dash
jarno
4
Ich überprüfe tatsächlich alle Bash-Skripte im aktuellen Verzeichnis auf Syntaxfehler, OHNE sie mit dem findTool auszuführen :
Beispiel:
find . -name '*.sh' -exec bash -n {} \;
Wenn Sie es für eine einzelne Datei verwenden möchten, bearbeiten Sie einfach den Platzhalter mit dem Namen der Datei.
Es funktioniert jedoch nicht, wenn Ihre Dateien nicht mit .shoder einer anderen mit Bash-Skripten verknüpften Erweiterung enden. Dies ist der Fall, wenn Sie die Skripte mit einem Template-Tool wie ERB generieren (dann enden sie mit .erb). Bitte stimmen Sie für youtrack.jetbrains.com/issue/IDEA-79574 ab, wenn Sie dies beheben möchten!
Greg Dubicki
1
Wenn Sie in einer Variablen die Gültigkeit aller Dateien in einem Verzeichnis benötigen (Git Pre-Commit-Hook, Build-Lint-Skript), können Sie die stderr-Ausgabe der Befehle "sh-n" oder "bash -n" abrufen (siehe andere) Antworten) in einer Variablen und haben ein "if / else" basierend darauf
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
Ändern Sie "sh" mit "bash", je nach Ihren Anforderungen
Antworten:
Vielleicht eine offensichtliche Einschränkung: Dies bestätigt Syntax aber nicht überprüfen , ob Ihr Bash - Skript versucht , einen Befehl auszuführen , die nicht in Ihrem Pfad ist, wie
ech hello
stattecho hello
.quelle
set
dies tun .if ["$var" == "string" ]
anstattif [ "$var" == "string" ]
type [
sagt "[ist eine eingebaute Shell". Es delegiert letztendlich an dastest
Programm, erwartet aber auch eine schließende Klammer. Es ist also so, wieif test"$var"
es der Autor nicht gemeint hat, aber syntaktisch gültig ist (sagen wir, $ var hat den Wert "a", dann sehen wir "bash: testa: Befehl nicht gefunden"). Punkt ist, dass syntaktisch kein Platz fehlt.[
wird in diesem Fall nur aufgerufen, wenn$var
es zu einer leeren Zeichenfolge erweitert wird . Wenn es$var
zu einer nicht leeren Zeichenfolge erweitert wird,[
wird es mit dieser Zeichenfolge verkettet und von Bash als Befehlsname (nicht Funktionsname ) interpretiert. Ja, das ist syntaktisch gültig, aber, wie Sie sagen, offensichtlich nicht die Absicht. Wenn Sie[[
anstelle von verwenden[
, obwohl[[
es sich um ein Shell- Schlüsselwort handelt (und nicht um ein integriertes Schlüsselwort), erhalten Sie dasselbe Ergebnis, da die unbeabsichtigte Verkettung von Zeichenfolgen die Erkennung des Schlüsselworts weiterhin überschreibt.["$var"
ist syntaktisch ein gültiger Befehlsnamenausdruck ; in ähnlicher Weise, Tokens==
und"$string"
gelten Befehl Argumente . ( Im Allgemeinen builtin[
mit geparst Befehlssyntax, während[[
- als Schalen Schlüsselwort - anders analysiert wird.) Die Schale builtin[
ist nicht übertragen auf das „test
Programm“ (externe Dienstprogramm):bash
,dash
,ksh
,zsh
haben alle eingebauten Versionen der beiden[
undtest
Und sie nicht nennen ihre Außen-Utility - Pendants.Zeit verändert alles. Hier ist eine Website, die eine Online-Syntaxprüfung für Shell-Skripte bietet.
Ich fand es sehr leistungsfähig, häufige Fehler zu erkennen.
Über ShellCheck
ShellCheck ist ein statisches Analyse- und Flusenwerkzeug für Sh / Bash-Skripte. Es konzentriert sich hauptsächlich auf die Behandlung typischer Syntaxfehler und Fallstricke für Anfänger und Fortgeschrittene, bei denen die Shell nur eine kryptische Fehlermeldung oder ein seltsames Verhalten ausgibt, berichtet jedoch auch über einige fortgeschrittenere Probleme, bei denen Eckfälle zu verzögerten Fehlern führen können.
Haskell-Quellcode ist auf GitHub verfügbar!
quelle
shellcheck
über Homebrew installieren :brew install shellcheck
.apt-get install shellcheck
trusty-backports
.Ich aktiviere auch die Option 'u' für jedes Bash-Skript, das ich schreibe, um zusätzliche Überprüfungen durchzuführen:
Dadurch wird die Verwendung nicht initialisierter Variablen gemeldet, wie im folgenden Skript 'check_init.sh'.
Ausführen des Skripts:
Wird folgendes melden:
Sehr nützlich, um Tippfehler zu fangen
quelle
set -u
obwohl dies die Frage nicht wirklich beantwortet, da Sie das Skript ausführen müssen, um die Fehlermeldung zu erhalten. Nicht einmalbash -n check_init.sh
zeigt diese WarnungFühren Sie dies aus. Wenn das Skript Syntaxfehler enthält, wird dieselbe Fehlermeldung zurückgegeben. Wenn es keine Fehler gibt, wird es ohne Meldung ausgegeben. Sie können dies sofort überprüfen, indem Sie
echo $?
die0
Bestätigung ohne Fehler als erfolgreich zurückgeben.Es hat bei mir gut funktioniert. Ich lief unter Linux OS, Bash Shell.
quelle
sh -n
wird wahrscheinlich nicht überprüfen, ob das Skript ein gültiges Bash-Skript ist. Es könnte falsche Negative geben.sh
ist eine Bourne-Shell-Variante, die normalerweise nicht Bash ist. Zum Beispiel in Ubuntu Linuxrealpath -e $(command -v sh)
gibt / bin / dashIch überprüfe tatsächlich alle Bash-Skripte im aktuellen Verzeichnis auf Syntaxfehler, OHNE sie mit dem
find
Tool auszuführen :Beispiel:
find . -name '*.sh' -exec bash -n {} \;
Wenn Sie es für eine einzelne Datei verwenden möchten, bearbeiten Sie einfach den Platzhalter mit dem Namen der Datei.
quelle
Der Befehl null [Doppelpunkt] ist auch beim Debuggen nützlich, um den Wert der Variablen anzuzeigen
quelle
set -x
jede ZeileEs gibt das BashSupport-Plugin für IntelliJ IDEA, das die Syntax überprüft.
quelle
.sh
oder einer anderen mit Bash-Skripten verknüpften Erweiterung enden. Dies ist der Fall, wenn Sie die Skripte mit einem Template-Tool wie ERB generieren (dann enden sie mit.erb
). Bitte stimmen Sie für youtrack.jetbrains.com/issue/IDEA-79574 ab, wenn Sie dies beheben möchten!Wenn Sie in einer Variablen die Gültigkeit aller Dateien in einem Verzeichnis benötigen (Git Pre-Commit-Hook, Build-Lint-Skript), können Sie die stderr-Ausgabe der Befehle "sh-n" oder "bash -n" abrufen (siehe andere) Antworten) in einer Variablen und haben ein "if / else" basierend darauf
Ändern Sie "sh" mit "bash", je nach Ihren Anforderungen
quelle