web-dev-qa-db-fra.com

Comment résoudre le problème "autorisation refusée" lors de l'utilisation de Sudo avec redirection dans Bash?

Lorsque j'utilise Sudo pour autoriser la modification de fichiers, je reçois régulièrement une "autorisation refusée".

Par exemple, ma souris est nerveuse et lente, je souhaite donc désactiver la scrutation:

Sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf

On me demande un mot de passe, puis on obtient:

bash: /etc/modprobe.d/local.conf: Permission denied

J'ai donc essayé de faire une modification temporaire pour désactiver la scrutation en utilisant:

Sudo echo N> /sys/module/drm_kms_helper/parameters/poll

Encore une fois, le système a répondu avec:

bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied

Des idées?

130
Jack

La redirection de sortie (via l'opérateur >) est effectuée par le shell et non par echo. Vous devez vous connecter en tant que root

Sudo -i

Ensuite, vous pouvez utiliser la redirection

echo N> /sys/module/drm_kms_helper/parameters/poll

Sinon, vous pouvez lancer bash string avec Sudo

Sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
149
shantanu

La redirection de sortie est effectuée par le shell à partir duquel la commande a été appelée. Alors, tout en morceaux, voici ce qui se passe *:

  • Shell appelle Sudo echo "options drm_kms_helper poll=N", qui exécute la commande Sudo avec la ligne de commande echo "options drm_kms_helper poll=N"

  • Sudo demande un mot de passe, ouvre le superutilisateur Shell et appelle echo "options drm_kms_helper poll=N", qui exécute la commande echo en le transmettant "options drm_kms_helper poll=N"

  • echo, exécuté avec les privilèges root, affiche la chaîne sur sa sortie standard.

  • La commande echo se termine, le superutilisateur se ferme, Sudo se termine

  • le shell à partir duquel la commande a été appelée collecte la sortie et tente de la rediriger vers /etc/modprobe.d/local.conf, qui est accessible en écriture uniquement par root. Il obtient l'erreur "autorisation refusée".

Pour résoudre ce problème, consultez la réponse de @shantanu.


(*) - Bien que la séquence ci-dessus aide à comprendre pourquoi la commande échoue, dans la réalité, les choses se passent un peu dans l’ordre: le shell original remarque la redirection et essaie d’ouvrir le fichier en écriture avant d’appeler la commande Sudo .... En cas d'échec de l'ouverture du fichier, le shell n'invoque même pas la commande qui était censée écrire dans le fichier (merci à @PanosRontogiannis de l'avoir signalé).

Voici un test rapide:

$ touch ./onlyroot.txt
$ Sudo chown root:root ./onlyroot.txt
$ Sudo bash -c "whoami | tee who.txt" > onlyroot.txt
bash: onlyroot.txt: Permission denied

Dans le test ci-dessus, le whoami | tee who.txt allait créer un fichier nommé who.txt contenant le mot "racine". Toutefois, lorsque la redirection de sortie échoue dans le shell appelant, le fichier "who.txt" est également manquant car la commande n'a pas été appelée.

74
Sergey

Ajoutant à la réponse de Shantanu:

... ou vous pouvez utiliser une commande tee comme ceci:

Sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10

ou si c'est la sortie d'une commande:

echo 10 | Sudo tee /sys/module/drm_kms_helper/parameters/poll
59
Untitled

Une approche que je n'ai pas vue mentionnée ici consiste simplement à exécuter la ligne de commande complète dans son propre shell. La page de manuel Sudo donne elle-même un exemple de cette approche:

Pour créer une liste d'utilisation des répertoires de la partition/home. Notez que cela exécute les commandes dans un sous-shell pour que la redirection de CD et de fichiers fonctionne.

$ Sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
14
kojiro

Sudo dd of=

Pour ajouter comme vous voulez:

echo inbytes | Sudo dd of=outfile oflag=append conv=notrunc

ou pour recréer le fichier à partir de zéro:

echo inbytes | Sudo dd of=outfile

Avantages:

  • plus beau que tee car aucune redirection /dev/null
  • plus beau que sh puisqu'il n'y a pas de sous-shell explicite (mais implicite pour la redirection)
  • dd a de nombreuses options puissantes, par exemple status=progress pour voir la progression du transfert

Fonctionne parce que Sudo transmet stdin à la commande.

Une autre option consiste à utiliser un fichier temporaire. Ceci est utile dans un script bash.

temp=$(mktemp)
echo "Hello, world!" > $temp
Sudo cp $temp /etc/wherever
3
user545424