Le script Bash imprime «Commande introuvable» sur des lignes vides

112

Chaque fois que j'exécute un script à bash scriptname.shpartir de la ligne de commande dans Debian, j'obtiens Command Not foundpuis le résultat du script.

Le script fonctionne mais il y a toujours une Command Not Founddéclaration imprimée à l'écran pour chaque ligne vide. Chaque ligne vide entraîne une commande introuvable.

J'exécute le script à partir du /vardossier.

Voici le script:

#!/bin/bash

echo Hello World

Je l'exécute en tapant ce qui suit:

bash testscript.sh

Pourquoi cela se produirait-il?

David
la source
Sérieusement, net est plein de telles plaintes. Shell est un interprète très faible et boiteux. Peu ici et là et ça échoue. Vous devez regarder même tous les espaces blancs dans le script. Mon script échouait à cause d'un caractère de saut de ligne invisible. Il ne s'agit probablement que d'un langage de script où les espaces blancs comptent!
Atul le
1
Utilisez bash -x scriptname.shpour tracer l'erreur. - Dans mon cas, c'était un fichier sh enregistré sous Windows avec VSCode et des fins de ligne comme "CRLF". Dans VSCode dans le coin inférieur droit, vous pouvez changer la terminaison de ligne de "CRLF" à "LF". Téléchargé ce fichier et peut enfin l'exécuter avec bash scriptname.sh.
Kai Noack
C'est certainement un doublon de stackoverflow.com/questions/39527571/ ... mais de nombreuses réponses ici expliquent un certain nombre d'autres situations où vous obtenez une "commande introuvable" pour d'autres raisons. Les visiteurs sont invités à lire toutes les réponses si votre problème ne concerne pas spécifiquement les lignes vides.
tripleee

Réponses:

162

Assurez-vous que votre première ligne est:

#!/bin/bash

Entrez votre chemin vers bash si ce n'est pas le cas /bin/bash


Essayez de courir:

dos2unix script.sh

Cela convertira les fins de ligne, etc. de Windows au format Unix. c'est-à-dire qu'il supprime \ r (CR) des fins de ligne pour les changer de \r\n (CR+LF)à \n (LF).

Plus de détails sur la dos2unixcommande (page de manuel)


Une autre façon de savoir si votre fichier est au format dos / Win:

cat scriptname.sh | sed 's/\r/<CR>/'

La sortie ressemblera à ceci:

#!/bin/sh<CR>
<CR>
echo Hello World<CR>
<CR>

Cela produira le texte entier du fichier avec <CR>affiché pour chaque \rcaractère dans le fichier.

chown
la source
Ce n'est probablement pas nécessaire puisqu'il l'exécute directement avec bash scriptname.sh(mais c'est toujours une bonne pratique, bien sûr).
paxdiablo
1
Salut #! / Bin / bash est la première ligne de mon script
David
1
@chown - J'ai eu le même problème sur Mac. Je suis tombé sur ce post. Je ne sais pas si cela a aidé l'OP ou non. Mais votre solution m'a aidé.
Prashant
1
Merci. C'était exactement le problème auquel j'étais confronté. Ces réponses l'ont fait fonctionner.
slayedbylucifer
5
Comment pouvez-vous écrire une réponse à une question de programmation pendant que vous conduisez?
Omar Tariq
61

Vous pouvez utiliser bash -x scriptname.shpour le tracer.

clyfish
la source
47

J'ai également rencontré un problème similaire. Le problème semble être les autorisations. Si vous faites une ls -l, vous pourrez peut-être identifier que votre fichier n'a peut-être PAS le bit d'exécution activé. Cela ne permettra PAS au script de s'exécuter. :)

Comme @artooro l'a ajouté dans le commentaire:

Pour résoudre ce problème, exécutez chmod +x testscript.sh

Lypso345
la source
4
Pour résoudre ce problème, exécutezchmod +x testscript.sh
artooro
C'était la réponse qui a fonctionné pour moi, on m'a toujours dit que je n'avais pas la permission, alors je l'ai sudo'ed et on m'a dit que la commande n'était pas trouvée. Je n'ai pas pensé à vérifier les permissions.
DiamondDrake
1
Merci Lypso345, cela a résolu le problème que j'avais.
ammills01
chmod 777 testscript.sh FTW
GeneCode
16

Cela peut être trivial et sans rapport avec la question du PO, mais je me suis souvent trompé au début lorsque j'apprenais le script.

VAR_NAME = $(hostname)
echo "the hostname is ${VAR_NAME}"  

Cela produira une réponse «commande non trouvée». La bonne façon est d'éliminer les espaces

VAR_NAME=$(hostname)
Altamont
la source
11

Si le script fait (relativement) bien son travail, alors il fonctionne correctement. Votre problème est probablement une seule ligne dans le fichier référençant un programme qui n'est pas sur le chemin, non installé, mal orthographié ou quelque chose de similaire.

Une façon est de placer un set -xen haut de votre script ou de l'exécuter avec bash -xau lieu de simplement bash- cela affichera les lignes avant de les exécuter et vous avez généralement juste besoin de regarder la sortie de la commande immédiatement avant l'erreur pour voir ce qui cause le problème

Si, comme vous le dites, ce sont les lignes vides à l' origine des problèmes, vous pouvez vérifier ce qui est actaully en eux. Courir:

od -xcb testscript.sh

et assurez-vous qu'il n'y a pas de caractères amusants "invisibles" comme le CTRL-M(retour chariot) que vous pouvez obtenir en utilisant un éditeur de type Windows.

paxdiablo
la source
+1 pour la commande 'od'! C'est cool, je n'en savais rien! Merci!
chown le
11

Sur Bash pour Windows, j'ai mal essayé de s'exécuter

run_me.sh 

sans ./ au début et a obtenu la même erreur.

Pour les personnes ayant un arrière-plan Windows, la forme correcte semble redondante:

./run_me.sh
Michael Freidgeim
la source
8

utiliser dos2unixsur votre fichier de script.

bash-o-logist
la source
6

pour exécuter cela, vous devez fournir le chemin complet de celui-ci par exemple

/home/Manuel/mywrittenscript
Masood Moghini
la source
En effet, le shell ne se soucie pas du tout des extensions de fichiers. Je ne suis pas sûr que cela mérite d'être affiché comme une réponse distincte.
tripleee
bien sûr .in système de fichiers linux contrairement aux extensions Windows sont utilisés simplement comme une partie du nom et ne disent rien sur le contenu du fichier. Je ne dois pas dire dans mon cas la contrainte.
Masood Moghini
6

Si vous avez Notepad ++ et que vous obtenez ce message d'erreur .sh: "commande introuvable" ou ce message d'erreur autoconf "ligne 615: ../../autoconf/bin/autom4te: aucun fichier ou répertoire de ce type" .

Sur votre Notepad ++, allez dans Edit -> EOL Conversion puis cochez Macinthos (CR) . Cela modifiera vos fichiers. J'encourage également à vérifier tous les fichiers avec cette commande, car une telle erreur se produira bientôt.

Juniar
la source
Merci pour cela. Pour mon cas, j'exécutais un script sur la distro busybox linux. Avait la même erreur "introuvable" dans toutes les lignes vides de mes scripts. il avait également des problèmes avec l'instruction if / else. changer EOL dans Notepad ++ à Unix l'a corrigé.
GeneCode
4

Avait le même problème. Malheureusement

dos2unix winfile.sh
bash: dos2unix: command not found

alors je l'ai fait pour convertir.

 awk '{ sub("\r$", ""); print }' winfile.sh > unixfile.sh

puis

bash unixfile.sh
Eugène Cuz
la source
2

Les problèmes liés à l'exécution des scripts peuvent également être liés à un mauvais formatage des commandes multilignes, par exemple si vous avez un espace après le saut de ligne "\". Par exemple ceci:

./run_me.sh \ 
--with-some parameter

(veuillez noter que l'espace supplémentaire après "\") causera des problèmes, mais lorsque vous supprimez cet espace, il fonctionnera parfaitement.

Marek Wysocki
la source
0

J'avais aussi quelques-uns des Cannot execute command. Tout semblait correct, mais en fait j'avais un espace insécable &nbsp;juste avant ma commande qui était bien sûr impossible à repérer à l'œil nu:

if [[ "true" ]]; then
  &nbsp;highlight --syntax js "var i = 0;"
fi

Ce qui, dans Vim, ressemblait à:

if [[ "true" ]]; then
  highlight --syntax js "var i = 0;"
fi

Ce n'est qu'après avoir exécuté le vérificateur de script Bash shellcheckque j'ai trouvé le problème.

Stefan van den Akker
la source
shellcheckest disponible en ligne, même si vous devez bien sûr copier et coller votre script exactement pour que cela vous aide. shellcheck.net
tripleee
0

Je suis tombé sur cela aujourd'hui, en copiant par inadvertance l'invite de commande dollar $(avant une chaîne de commande) dans le script.

CNSKnight
la source
-1

Ajoutez le répertoire courant (.) À PATH pour pouvoir exécuter un script, en tapant simplement son nom, qui réside dans le répertoire courant:

PATH=.:$PATH
Mike Goethals
la source
1
Ceci est considéré comme une vulnérabilité de sécurité. N'AJOUTEZ PAS .À VOTRE CHEMIN.
gniourf_gniourf
Explication sur les raisons pour lesquelles cette "réponse" est une mauvaise idée: superuser.com/questions/156582/…
jmng
-1

Vous pouvez mettre à jour vos fichiers .bashrc et .bash_profile avec des alias pour reconnaître la commande que vous entrez.

Les fichiers .bashrc et .bash_profile sont des fichiers cachés probablement situés sur votre lecteur C: où vous enregistrez vos fichiers programme.

Kean Amaral
la source