È possibile controllare una sintassi dello script bash senza eseguirla?
Usando Perl, posso correre perl -c 'script name'
. Esiste un comando equivalente per gli script bash?
È possibile controllare una sintassi dello script bash senza eseguirla?
Usando Perl, posso correre perl -c 'script name'
. Esiste un comando equivalente per gli script bash?
Risposte:
bash -n scriptname
Forse un ovvio avvertimento: questo convalida la sintassi ma non verificherà se il tuo script bash tenta di eseguire un comando che non è nel tuo percorso, come ech hello
invece di echo hello
.
set
fanno.
if ["$var" == "string" ]
anzichéif [ "$var" == "string" ]
type [
dice "[è una shell integrata". Alla fine delega al test
programma, ma si aspetta anche una parentesi di chiusura. Quindi è come if test"$var"
, non è quello che intendeva l'autore, ma è sintatticamente valido (diciamo che $ var ha un valore di "a", quindi vedremo "bash: testa: comando non trovato"). Il punto è che sintatticamente, non c'è spazio mancante.
[
in questo caso il comando incorporato viene invocato solo se si $var
verifica l'espansione in una stringa vuota . Se si $var
espande in una stringa non vuota , [
viene concatenato con quella stringa e viene interpretato come un nome di comando (non il nome della funzione ) da Bash e, sì, che è sintatticamente valido, ma, come dici tu, ovviamente non è l'intento. Se si utilizza [[
invece di [
, anche se [[
è una parola chiave shell (piuttosto che un built-in), si otterrà lo stesso risultato, poiché la concatenazione di stringhe non intenzionali ignora ancora il riconoscimento della parola chiave.
["$var"
è un'espressione nome-comando valida ; allo stesso modo, i token e sono validi argomenti di comando . (In generale, incorporato viene analizzato con comando sintassi, mentre - come un guscio parola - viene analizzato in modo diverso.) Il comando incorporato shell non non delegare al " programma" (utilità esterna): , , , tutti hanno incorporato versioni sia e==
"$string"
[
[[
[
test
bash
dash
ksh
zsh
[
test
e non chiamano le loro controparti di utilità esterna.
Il tempo cambia tutto. Ecco un sito Web che fornisce il controllo della sintassi online per lo script della shell.
Ho scoperto che è molto potente rilevare errori comuni.
ShellCheck è uno strumento statico di analisi e sfilacciatura di script sh / bash. Si concentra principalmente sulla gestione di errori e insidie tipiche della sintassi per principianti e di livello intermedio in cui la shell fornisce solo un messaggio di errore criptico o un comportamento strano, ma riporta anche alcuni problemi più avanzati in cui casi d'angolo possono causare guasti ritardati.
Il codice sorgente di Haskell è disponibile su GitHub!
apt-get install shellcheck
trusty-backports
.
Abilito anche l'opzione 'u' su ogni script bash che scrivo per fare qualche controllo extra:
set -u
Questo riporterà l'utilizzo di variabili non inizializzate, come nel seguente script 'check_init.sh'
#!/bin/sh
set -u
message=hello
echo $mesage
Esecuzione dello script:
$ check_init.sh
Riporterà quanto segue:
./check_init.sh[4]: mesage: parametro non impostato.
Molto utile per catturare errori di battitura
set -u
sebbene questo non risponda realmente alla domanda, perché è necessario eseguire lo script per ottenere il messaggio di errore. Nemmeno bash -n check_init.sh
mostra
sh -n script-name
Esegui questo. Se ci sono errori di sintassi nello script, restituisce lo stesso messaggio di errore. Se non ci sono errori, viene fuori senza dare alcun messaggio. Puoi controllare immediatamente usando echo $?
, che restituirà la 0
conferma avvenuta senza errori.
Ha funzionato bene per me. Ho funzionato su un sistema operativo Linux, Bash Shell.
sh -n
probabilmente non verificherà che lo script sia script Bash valido. Potrebbe dare falsi negativi. sh
è una variante della shell Bourne che di solito non è Bash. Ad esempio in Ubuntu Linux realpath -e $(command -v sh)
dà / bin / dash
Veramente controllo tutti gli script bash nella directory corrente per errori di sintassi SENZA eseguirli usando lo find
strumento:
Esempio:
find . -name '*.sh' -exec bash -n {} \;
Se vuoi usarlo per un singolo file, modifica il carattere jolly con il nome del file.
Esiste un plug-in BashSupport per IntelliJ IDEA che controlla la sintassi.
.sh
o con altre estensioni associate agli script Bash, questo è il caso se generi gli script usando uno strumento di template come ERB (quindi finiscono con .erb
). Si prega di votare per youtrack.jetbrains.com/issue/IDEA-79574 se lo si desidera risolto!
Se hai bisogno in una variabile della validità di tutti i file in una directory (git pre-commit hook, build lint script), puoi catturare l'output stderr dei comandi "sh -n" o "bash -n" (vedi altri risposte) in una variabile e hanno un "if / else" basato su quello
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
Cambia "sh" con "bash" a seconda delle tue esigenze