Question Comment utiliser sudo pour rediriger la sortie vers un emplacement pour lequel je n'ai pas l'autorisation d'écrire?


On m'a donné un accès sudo sur l'une de nos boîtes Linux de développement RedHat, et il me semble que j'ai souvent besoin de rediriger la sortie vers un emplacement auquel je n'ai normalement pas accès en écriture.

Le problème est, cet exemple artificiel ne fonctionne pas:

sudo ls -hal /root/ > /root/test.out

Je reçois juste la réponse:

-bash: /root/test.out: Permission denied

Comment puis-je faire en sorte que cela fonctionne?


696
2017-09-17 11:44


origine


Réponses:


Votre commande ne fonctionne pas car la redirection est effectuée par votre shell qui n'a pas l'autorisation d'écrire /root/test.out. La redirection de la sortie n'est pas effectuée par sudo.

Il y a plusieurs solutions:

  • Exécutez un shell avec sudo et donnez-lui la commande en utilisant le -c option:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Créez un script avec vos commandes et exécutez ce script avec sudo:

    #!/bin/sh
    ls -hal /root/ > /root/test.out
    

    Courir sudo ls.sh. Voir Steve Bennett répondre si vous ne voulez pas créer un fichier temporaire.

  • Lancer un shell avec sudo -s puis lancez vos commandes:

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • Utilisation sudo tee (Si vous devez vous échapper beaucoup en utilisant le -c option):

    sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
    

    La redirection vers /dev/null est nécessaire pour arrêter tee de sortie à l'écran. À ajouter au lieu d'écraser le fichier de sortie (>>), utilisation tee -a ou tee --append (le dernier est spécifique à GNU coreutils).

Merci à Jd, Adam J. Forster et Johnathan pour les deuxième, troisième et quatrième solutions.


975
2017-09-17 11:48



Quelqu'un ici vient de suggérer un tee sudoing:

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

Cela peut également être utilisé pour rediriger n'importe quelle commande vers un répertoire auquel vous n'avez pas accès. Cela fonctionne parce que le programme tee est effectivement un programme "echo to a file", et la redirection vers / dev / null consiste à l'empêcher de sortir à l'écran pour le garder identique à l'exemple inventé original ci-dessus.


80
2017-09-17 12:26



Un tour que j'ai compris moi-même était

sudo ls -hal /root/ | sudo dd of=/root/test.out

65
2017-11-21 14:24



Le problème est que le commander se court sous sudo, mais le redirection se lance sous votre utilisateur. Ceci est fait par le shell et il y a très peu de choses que vous pouvez faire à ce sujet.

sudo command > /some/file.log
`-----v-----'`-------v-------'
   command       redirection

Les moyens habituels de contourner ceci sont:

  • Enveloppez les commandes dans un script que vous appelez sous sudo.

    Si les commandes et / ou le fichier journal change, vous pouvez script les prend comme arguments. Par exemple:

    sudo log_script command /log/file.txt
    
  • Appelez un shell et passez la ligne de commande en paramètre avec -c

    Ceci est particulièrement utile pour les commandes composées. Par exemple:

    sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    

38
2017-09-23 10:10



Encore une autre variation sur le thème:

sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

Ou bien sûr:

echo 'ls -hal /root/ > /root/test.out' | sudo bash

Ils ont l'avantage (minuscule) que vous n'avez pas besoin de se souvenir des arguments sudo ou sh/bash


18
2018-05-13 03:53



Faites sudo exécuter un shell, comme ceci:

sudo sh -c "echo foo > ~root/out"

15
2017-09-17 11:48



Clarifier un peu pourquoi l'option tee est préférable

En supposant que vous ayez la permission d'exécuter la commande qui crée la sortie, si vous redirigez la sortie de votre commande au tee, vous devez seulement élever les privilèges de tee avec sudo et direct tee pour écrire (ou ajouter) au fichier en question.

dans l'exemple donné dans la question, cela signifierait:

ls -hal /root/ | sudo tee /root/test.out

pour quelques exemples plus pratiques:

# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts

# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4

Dans chacun de ces exemples, vous prenez la sortie d'une commande non-privilégiée et vous écrivez dans un fichier qui n'est généralement accessible qu'en écriture par root, ce qui est l'origine de votre question.

C'est une bonne idée de le faire de cette façon parce que la commande qui génère la sortie n'est pas exécutée avec des privilèges élevés. Cela ne semble pas avoir d'importance ici echo mais quand la commande source est un script que vous n'avez pas entièrement confiance, c'est crucial.

Notez que vous pouvez utiliser l'option -a pour ajouter à append (comme >>) au fichier cible plutôt que de l'écraser (comme >).


14
2017-11-02 01:51