J'ai un script appelé foo.sh
dans mon dossier personnel.
Lorsque je navigue dans ce dossier et saisis ./foo.sh
, je reçois
-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 résoudre le problème?
Autorisation refusée
Pour exécuter un script, le fichier doit avoir un bit d’autorisation exécutable défini .
Pour bien comprendre Linux permissions sur les fichiers , vous pouvez étudier la documentation de la commande chmod
. chmod , abréviation de change mode , 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 chmod
ou info chmod
à partir de la ligne de commande. Une fois lu et compris, vous devriez être capable 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 toutes les personnes qui ne sont ni le propriétaire du fichier ni un membre du groupe auquel le fichier appartient (ce dernier groupe d'autorisations est parfois appelé comme "monde" ou "autre")
Voici un résumé de la procédure à suivre pour résoudre l'erreur Permission Denied 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 a un accès en lecture et en écriture rw mais le - indique que l'autorisation exécutable est manquante
La commande chmod
résout ce problème. (Le groupe et les autres ont uniquement des autorisations de lecture sur le fichier, ils ne peuvent ni 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 a pour résultat une commande introuvable
Lorsque vous exécutez une commande à l'aide de Sudo , vous l'exécutez en tant que superutilisateur ou racine.
La raison pour laquelle l'utilisateur root ne trouve pas votre commande est probablement que la variable d'environnement PATH
pour root n'inclut pas le répertoire où se trouve foo.sh
. Par conséquent, la commande n'est pas trouvée.
La variable d’environnement PATH contient une liste de répertoires dans lesquels des 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 fonctionner
env | grep ^PATH
Voici un exemple de sortie de l'exécution de la commande env
ci-dessus en tant qu'utilisateur ordinaire, puis en tant qu'utilisateur root sous 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 PATH, l’utilisateur non privilégié (rkielty) et le super-utilisateur ne sont pas .
Le répertoire dans lequel foo.sh
réside n'est pas présent dans la variable PATH de l'utilisateur racine, d'où l'erreur non trouvée de la commande.
Les autres solutions que j'ai vues jusqu'ici sont basées sur des définitions de système, mais il est en fait possible que Sudo
utilise la version courante PATH
(avec la commande env
) et/ou le reste de l'environnement (avec l'option -E
) simplement en l'invoquant à droite:
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-même Sudo
en remplaçant l'original Sudo
.)
Recherchez 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 $PATH
est remplacé, utilisez visudo
et modifiez /etc/sudoers
.
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
chmod +x foo.sh
#!/bin/sh
ou quelque chose de ce genre.Sudo pwd
Vous pouvez également créer un lien symbolique vers votre script dans l'un des répertoires (/usr/local/bin
, par exemple) dans le super-utilisateur 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.
Essayez chmod u+x foo.sh
au lieu de chmod +x foo.sh
si vous rencontrez des difficultés avec les guides ci-dessus. Cela a fonctionné pour moi alors que les autres solutions ne fonctionnaient pas.
Ok ceci 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 ROOT sans avoir à exporter à la source PATH = $ PATH:/home/votre_utilisateur/bin à chaque fois.
Notez que j’ai besoin d’être explicite lors de l’ajout de PATH car HOME pour superutilisateur est/root
Il semble que linux dira "commande introuvable" même si vous indiquez explicitement le chemin d'accès au 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 c'est probablement techniquement correct. Un fichier n'est pas une commande jusqu'à son exécutable et ne peut donc pas être trouvé.
Il y a d'excellentes réponses ci-dessus. Si, après les avoir essayés, vous obtenez toujours command not found
réessayez avec le chemin d'accès complet au fichier:
Sudo /home/user/path/to/foo.sh