Commande introuvable lors de l'utilisation de sudo

146

J'ai un script appelé foo.shdans mon dossier personnel.

Lorsque je navigue vers ce dossier et que j'entre ./foo.sh, j'obtiens

-bash: ./foo.sh: Permission denied.

Quand j'utilise sudo ./foo.sh, je reçois

sudo: foo.sh: command not found.

Pourquoi cela se produit-il et comment puis-je y remédier?

Neko
la source

Réponses:

151

Permission refusée

Pour exécuter un script, le fichier doit avoir un bit d'autorisation exécutable défini .

Afin de bien comprendre les autorisations des fichiers Linux , vous pouvez étudier la documentation de la chmodcommande. chmod , une abréviation de mode de modification , est la commande utilisée pour modifier les paramètres d'autorisation d'un fichier.

Pour lire la documentation chmod de votre système local, exécutez man chmodou à info chmodpartir de la ligne de commande. Une fois lu et compris, vous devriez être en mesure de comprendre le résultat de l'exécution ...

ls -l foo.sh

... qui répertorie les autorisations READ, WRITE et EXECUTE pour le propriétaire du fichier, le propriétaire du groupe et tous les autres qui ne sont pas le propriétaire du fichier ou un membre du groupe auquel appartient le fichier (ce dernier groupe d'autorisations est parfois appelé comme "monde" ou "autre")

Voici un résumé de la façon de résoudre l' erreur Autorisation refusée dans votre cas.

$ ls -l foo.sh                    # Check file permissions of foo
-rw-r--r-- 1 rkielty users 0 2012-10-21 14:47 foo.sh 
    ^^^ 
 ^^^ | ^^^   ^^^^^^^ ^^^^^
  |  |  |       |       | 
Owner| World    |       |
     |          |    Name of
   Group        |     Group
             Name of 
              Owner 

Le propriétaire dispose d'un accès en lecture et en écriture rw mais le - indique que l'autorisation exécutable est manquante

La chmodcommande corrige cela. (Les groupes et autres n'ont que des autorisations de lecture définies sur le fichier, ils ne peuvent pas y écrire ni l'exécuter)

$ chmod +x foo.sh               # The owner can set the executable permission on foo.sh
$ ls -l foo.sh                  # Now we see an x after the rw 
-rwxr-xr-x 1 rkielty users 0 2012-10-21 14:47 foo.sh
   ^  ^  ^

foo.sh est maintenant exécutable en ce qui concerne Linux.

L'utilisation de sudo résultats dans la commande introuvable

Lorsque vous exécutez une commande à l'aide de sudo, vous l'exécutez effectivement en tant que superutilisateur ou root.

La raison pour laquelle l'utilisateur root ne trouve pas votre commande est probablement que la PATHvariable d'environnement pour root n'inclut pas le répertoire où foo.shse trouve . Par conséquent, la commande n'est pas trouvée.

La variable d'environnement PATH contient une liste de répertoires dans lesquels les commandes sont recherchées. Chaque utilisateur définit sa propre variable PATH en fonction de ses besoins. Pour voir ce qu'il est configuré pour s'exécuter

env | grep ^PATH

Voici un exemple de sortie de l'exécution de la envcommande ci-dessus en tant qu'utilisateur ordinaire, puis en tant qu'utilisateur root à l'aide de sudo

rkielty@rkielty-laptop:~$ env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

rkielty@rkielty-laptop:~$ sudo env | grep ^PATH
[sudo] password for rkielty: 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin

Notez que, bien que similaires, dans ce cas, les répertoires contenus dans le PATH l'utilisateur non privilégié (rkielty) et le super utilisateur ne sont pas les mêmes .

Le répertoire où foo.shréside n'est pas présent dans la variable PATH de l'utilisateur root, d'où l' erreur command not found .

Rob Kielty
la source
1
@Nakilon si vous posez cela dans une question avec tous les détails, je devrais être en mesure de le résoudre pour vous plus loin. Le problème est probablement de savoir quel shell (votre premier shell de commande ou le shell lancé par sudo) a évalué $ PWD
Rob Kielty
6
@Rob: alors comment fait - on sudo« est PATHla même chose que de l'utilisateur?
Tom
1
@Rob: j'ai trouvé un moyen entre-temps (voir ma réponse ci-dessous).
Tom
1
J'aime la façon dont tu m'as expliqué! Merci :)
Kasparov92
1
@Tom, vous pouvez changer le secure_path dans / etc / sudoers
DennisLi
98

Les autres solutions que j'ai vues ici jusqu'à présent sont basées sur certaines définitions du système, mais il est en fait possible d'avoir sudoutiliser le courant PATH(avec la envcommande) et / ou le reste de l'environnement (avec l' -Eoption) juste en l'appelant correctement :

sudo -E env "PATH=$PATH" <command> [arguments]

En fait, on peut en faire un alias:

alias mysudo='sudo -E env "PATH=$PATH"'

(Il est également possible de nommer l'alias lui sudo- même , en remplaçant l'original sudo.)

À M
la source
3
J'aime cette solution, Tom, parce que vous travaillez consciemment avec une autre invocation sudo. Il est important de garder à l'esprit la variable PATH utilisée à tout moment, quelle que soit la manière (et il y en a beaucoup) qu'elle est configurée.
Rob Kielty
4
Je pense que c'est la solution correcte et la plus standardisée pour les command not foundproblèmes rencontrés dans la distribution Ubuntu. Merci mec.
Omar Tariq
vous pouvez ajouter l'alias à votre ./bashrcpour l'enregistrer entre les sessions
George
19

Vérifier les secure_path sur sudo

[root@host ~]# sudo -V | grep 'Value to override'
Value to override user's $PATH with: /sbin:/bin:/usr/sbin:/usr/bin

Si $PATHest remplacé, utilisez visudoet modifiez/etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
codemonkee
la source
Merci! Cela a aidé à résoudre un mystère de sudo ne pouvant pas exécuter de commandes.
Evgeny Goldin
7
  1. Vérifiez que vous disposez de l'autorisation d'exécution sur le script. c'est à direchmod +x foo.sh
  2. Vérifiez que la première ligne de ce script est #!/bin/shou une telle.
  3. Pour sudo, vous êtes dans le mauvais répertoire. vérifier avecsudo pwd
Ed Heal
la source
5

Vous pouvez également créer un lien logiciel vers votre script dans l'un des répertoires ( /usr/local/binpar exemple) du superutilisateur PATH. Il sera alors disponible pour le sudo.

chmod +x foo.sh
sudo ln -s path-to-foo.sh /usr/local/bin/foo

Jetez un œil à cette réponse pour avoir une idée du répertoire dans lequel placer le lien logiciel.

TrigonaMinima
la source
2

Il semble que Linux dira "commande introuvable" même si vous indiquez explicitement le chemin du fichier.

[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
sudo: /tmp/uid.sh: command not found
1
[veeam@jsandbox ~]$ chmod +x /tmp/uid.sh
[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
0

C'est une erreur quelque peu trompeuse, mais elle est probablement techniquement correcte. Un fichier n'est pas une commande avant son exécutable et ne peut donc pas être trouvé.

Jeff MacDonald
la source
1

Ok, c'est ma solution: dans ~ / .bash_aliases, ajoutez simplement ce qui suit:

# ADDS MY PATH WHEN SET AS ROOT
if [ $(id -u) = "0" ]; then
   export PATH=$PATH:/home/your_user/bin 
fi

Voila! Vous pouvez maintenant exécuter vos propres scripts avec sudo ou définir comme ROOT sans avoir à faire d'export PATH = $ PATH: / home / your_user / bin à chaque fois.

Notez que je dois être explicite lors de l'ajout de mon PATH puisque HOME pour le superutilisateur est / root

Fernando D Jaime
la source
1

Essayez chmod u+x foo.shplutôt que chmod +x foo.shsi vous rencontrez des problèmes avec les guides ci-dessus. Cela a fonctionné pour moi quand les autres solutions n'ont pas fonctionné.

Que contient une recherche Google
la source
1

Il y a d'excellentes réponses ci-dessus. Si, après les avoir essayés, vous obtenez toujours command not foundréessayer avec le chemin d'accès complet du fichier:

sudo /home/user/path/to/foo.sh
IggyM
la source