Peut-être une mise en garde évidente: cela valide la syntaxe mais ne vérifie pas si votre script bash essaie d'exécuter une commande qui n'est pas sur votre chemin, comme à la ech helloplace de echo hello.
Dans la page de manuel de bash, sous "SHELL BUILTIN COMMANDS / set", -n est documenté, et comme l'indique le début de la page de manuel, bash interprète toutes les options à caractère unique qui le setfont.
ephémient
24
pour ajouter à la mise en garde non évidente (pour moi), il ne détectera pas non plus une erreur causée par un espace manquant if ["$var" == "string" ]au lieu deif [ "$var" == "string" ]
Brynjar
11
@Brynjar C'est parce que c'est juste une vérification de la syntaxe. Le crochet ouvert n'est pas une syntaxe, c'est le nom de la fonction à exécuter. type [dit "[est un shell intégré". Il délègue finalement au testprogramme, mais il s'attend également à une clôture. Donc c'est comme if test"$var", ce qui n'est pas ce que l'auteur voulait dire, mais qui est syntaxiquement valide (disons que $ var a une valeur de "a", alors nous verrons "bash: testa: commande introuvable"). Le point est que syntaxiquement, il n'y a pas d'espace manquant.
Joshua Cheek
2
@JoshuaCheek: la fonction intégrée [n'est invoquée dans ce cas que si elle $varse développe sur une chaîne vide . Si se $vardéveloppe en une chaîne non vide , [est concaténé avec cette chaîne et est interprété comme un nom de commande (pas un nom de fonction ) par Bash, et, oui, c'est syntaxiquement valide, mais, comme vous le dites, évidemment pas l'intention. Si vous utilisez à la [[place de [, même s'il [[s'agit d'un mot clé shell (plutôt que d'un mot clé intégré), vous obtiendrez le même résultat, car la concaténation de chaîne involontaire remplace toujours la reconnaissance du mot clé.
mklement0
2
@JoshuaCheek: Bash est toujours une vérification de syntaxe ici: il vérifie la syntaxe d' invocation de commande simple : ["$var"est syntaxiquement une expression de nom de commande valide ; de même, les jetons ==et "$string"sont des arguments de commande valides . ( En général, builtin [est analysé avec commande syntaxe, tandis que [[- comme une coquille mot - clé - est analysé différemment.) La commande interne shell [ne pas déléguer au « testprogramme » (utilitaire externe): bash, dash, ksh, zshtous ont intégré les versions des deux [ettestet ils n'appellent pas leurs homologues externes.
mklement0
127
Le temps change tout. Voici un site Web qui fournit une vérification de la syntaxe en ligne pour le script shell.
J'ai trouvé qu'il est très puissant pour détecter les erreurs courantes.
À propos de ShellCheck
ShellCheck est un outil d'analyse statique et de peluchage pour les scripts sh / bash. Il est principalement axé sur la gestion des erreurs de syntaxe et des pièges de niveau débutant et intermédiaire typiques lorsque le shell donne simplement un message d'erreur cryptique ou un comportement étrange, mais il signale également quelques problèmes plus avancés où les cas d'angle peuvent provoquer des échecs retardés.
Le code source de Haskell est disponible sur GitHub!
Excellent conseil; sur OSX vous pouvez également installer le CLI shellcheck.net, shellcheckvia Homebrew : brew install shellcheck.
mklement0
3
Aussi sur Debian et ses amis:apt-get install shellcheck
cet autre gars
Pour Ubuntu trusty, ce paquet doit être installé depuis trusty-backports.
Peterino
Comme mentionné ci-dessus, une dépendance fiable est nécessaire et peut l'installer comme ci-dessous dans Ubuntu 14.04: sudo apt-get -f install, puis: sudo sudo apt-get install shellcheck
zhihong
C'est vraiment utile, mais il n'utilise pas l'analyseur de Bash mais le sien. Dans la plupart des cas, c'est assez bon et cela peut identifier à la fois l'analyse et d'autres problèmes, mais il y a au moins un cas de bord (et probablement d'autres que je n'ai pas vu) où il n'analyse pas tout à fait de la même manière.
Daniel H
38
J'active également l'option 'u' sur chaque script bash que j'écris afin de faire des vérifications supplémentaires:
set-u
Cela signalera l'utilisation de variables non initialisées, comme dans le script suivant 'check_init.sh'
je mets toujours ces drapeaux dans mes scripts bash, si ça passe, c'est bon d'aller "set -o errexit" "set -o nounset" "set -o pipefail"
μολὼν.λαβέ
+1 pour set -ubien que cela ne réponde pas vraiment à la question, car vous devez exécuter le script pour obtenir le message d'erreur. Ne bash -n check_init.shmontre même pas cet avertissement
rubo77
23
sh -n script-name
Lance ça. S'il y a des erreurs de syntaxe dans le script, il renvoie le même message d'erreur. S'il n'y a pas d'erreur, il sort sans donner de message. Vous pouvez vérifier immédiatement en utilisant echo $?, qui retournera 0confirmant le succès sans aucune erreur.
Cela a bien fonctionné pour moi. J'ai couru sous Linux OS, Bash Shell.
Bien qu'il ne soit pas exactement lié à la vérification de la syntaxe bash - utiliser set -x et set + x pour déboguer le script complet ou des sections du script est très utile
GuruM
Merci pour cela je ne savais pas ne connaissais pas le -n mais ce que je voulais c'était @GuruM> sh -x test.sh car cela affiche la sortie générée du script
zzapper
1
Oui. J'ai oublié de mentionner que vous pouvez faire ce qui suit sur la ligne de commande: 1) bash -x test.sh #this exécute l'ensemble du script en «mode débogage» 2) set + x; bash test.sh; set -x #set debug mode on / off before / after script run Dans le script: a) #! / bin / bash -x #add 'debug mode' en haut du script b) set + x; code; set -x #add 'debug mode' pour n'importe quelle section du script
GuruM
sh -nne vérifiera probablement pas que le script est un script Bash valide. Cela pourrait donner de faux négatifs. shest une variante du shell Bourne qui n'est généralement pas Bash. Par exemple dans Ubuntu Linux realpath -e $(command -v sh)donne / bin / dash
jarno
4
Je vérifie en fait tous les scripts bash dans le répertoire actuel pour les erreurs de syntaxe SANS les exécuter à l'aide de l' findoutil:
Exemple:
find . -name '*.sh' -exec bash -n {} \;
Si vous souhaitez l'utiliser pour un seul fichier, modifiez simplement le caractère générique avec le nom du fichier.
Mais cela ne fonctionnera pas si vos fichiers ne se terminent pas par .shou une autre extension associée aux scripts Bash, ce qui est le cas si vous générez les scripts à l'aide d'un outil de modélisation comme ERB (puis ils se terminent par .erb). Votez pour youtrack.jetbrains.com/issue/IDEA-79574 si vous voulez le réparer!
Greg Dubicki
1
Si vous avez besoin dans une variable de la validité de tous les fichiers d'un répertoire (git pre-commit hook, build lint script), vous pouvez attraper la sortie stderr des commandes "sh -n" ou "bash -n" (voir autres réponses) dans une variable, et avoir un "si / autre" basé sur cette
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
Réponses:
Peut-être une mise en garde évidente: cela valide la syntaxe mais ne vérifie pas si votre script bash essaie d'exécuter une commande qui n'est pas sur votre chemin, comme à la
ech hello
place deecho hello
.la source
set
font.if ["$var" == "string" ]
au lieu deif [ "$var" == "string" ]
type [
dit "[est un shell intégré". Il délègue finalement autest
programme, mais il s'attend également à une clôture. Donc c'est commeif test"$var"
, ce qui n'est pas ce que l'auteur voulait dire, mais qui est syntaxiquement valide (disons que $ var a une valeur de "a", alors nous verrons "bash: testa: commande introuvable"). Le point est que syntaxiquement, il n'y a pas d'espace manquant.[
n'est invoquée dans ce cas que si elle$var
se développe sur une chaîne vide . Si se$var
développe en une chaîne non vide ,[
est concaténé avec cette chaîne et est interprété comme un nom de commande (pas un nom de fonction ) par Bash, et, oui, c'est syntaxiquement valide, mais, comme vous le dites, évidemment pas l'intention. Si vous utilisez à la[[
place de[
, même s'il[[
s'agit d'un mot clé shell (plutôt que d'un mot clé intégré), vous obtiendrez le même résultat, car la concaténation de chaîne involontaire remplace toujours la reconnaissance du mot clé.["$var"
est syntaxiquement une expression de nom de commande valide ; de même, les jetons==
et"$string"
sont des arguments de commande valides . ( En général, builtin[
est analysé avec commande syntaxe, tandis que[[
- comme une coquille mot - clé - est analysé différemment.) La commande interne shell[
ne pas déléguer au «test
programme » (utilitaire externe):bash
,dash
,ksh
,zsh
tous ont intégré les versions des deux[
ettest
et ils n'appellent pas leurs homologues externes.Le temps change tout. Voici un site Web qui fournit une vérification de la syntaxe en ligne pour le script shell.
J'ai trouvé qu'il est très puissant pour détecter les erreurs courantes.
À propos de ShellCheck
ShellCheck est un outil d'analyse statique et de peluchage pour les scripts sh / bash. Il est principalement axé sur la gestion des erreurs de syntaxe et des pièges de niveau débutant et intermédiaire typiques lorsque le shell donne simplement un message d'erreur cryptique ou un comportement étrange, mais il signale également quelques problèmes plus avancés où les cas d'angle peuvent provoquer des échecs retardés.
Le code source de Haskell est disponible sur GitHub!
la source
shellcheck
via Homebrew :brew install shellcheck
.apt-get install shellcheck
trusty-backports
.J'active également l'option 'u' sur chaque script bash que j'écris afin de faire des vérifications supplémentaires:
Cela signalera l'utilisation de variables non initialisées, comme dans le script suivant 'check_init.sh'
Exécution du script:
Rapportera les éléments suivants:
Très utile pour attraper les fautes de frappe
la source
set -u
bien que cela ne réponde pas vraiment à la question, car vous devez exécuter le script pour obtenir le message d'erreur. Nebash -n check_init.sh
montre même pas cet avertissementLance ça. S'il y a des erreurs de syntaxe dans le script, il renvoie le même message d'erreur. S'il n'y a pas d'erreur, il sort sans donner de message. Vous pouvez vérifier immédiatement en utilisant
echo $?
, qui retournera0
confirmant le succès sans aucune erreur.Cela a bien fonctionné pour moi. J'ai couru sous Linux OS, Bash Shell.
la source
sh -n
ne vérifiera probablement pas que le script est un script Bash valide. Cela pourrait donner de faux négatifs.sh
est une variante du shell Bourne qui n'est généralement pas Bash. Par exemple dans Ubuntu Linuxrealpath -e $(command -v sh)
donne / bin / dashJe vérifie en fait tous les scripts bash dans le répertoire actuel pour les erreurs de syntaxe SANS les exécuter à l'aide de l'
find
outil:Exemple:
find . -name '*.sh' -exec bash -n {} \;
Si vous souhaitez l'utiliser pour un seul fichier, modifiez simplement le caractère générique avec le nom du fichier.
la source
commande null [deux points] également utile lors du débogage pour voir la valeur de la variable
la source
set -x
affiche chaque ligne avant son exécutionIl existe un plugin BashSupport pour IntelliJ IDEA qui vérifie la syntaxe.
la source
.sh
ou une autre extension associée aux scripts Bash, ce qui est le cas si vous générez les scripts à l'aide d'un outil de modélisation comme ERB (puis ils se terminent par.erb
). Votez pour youtrack.jetbrains.com/issue/IDEA-79574 si vous voulez le réparer!Si vous avez besoin dans une variable de la validité de tous les fichiers d'un répertoire (git pre-commit hook, build lint script), vous pouvez attraper la sortie stderr des commandes "sh -n" ou "bash -n" (voir autres réponses) dans une variable, et avoir un "si / autre" basé sur cette
Changez "sh" par "bash" selon vos besoins
la source