Comment utiliser sudo pour rediriger la sortie vers un endroit où je n'ai pas la permission d'écrire?

on m'a donné l'accès sudo sur l'une de nos boîtes RedHat linux de développement, et je semble me trouver assez souvent avoir besoin de rediriger la sortie à un endroit où je n'ai pas normalement l'accès en écriture.

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

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

je viens de recevoir la réponse:

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

Comment faire pour que ça marche?

718
demandé sur smci 2008-09-17 15:44:39

15 réponses

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

il y a plusieurs solutions:

  • lancez un shell avec sudo et donnez-lui la commande en utilisant l'option -c :

    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
    

    Exécuter sudo ls.sh . Voir Steve Bennett réponse si vous ne voulez pas créer un fichier temporaire.

  • lancez 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]$
    
  • utilisez sudo tee -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 la sortie vers l'écran. À ajouter au lieu d'écraser le fichier de sortie ( >> ), utilisez 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.

1000
répondu Cristian Ciupitu 2017-05-23 10:31:16

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

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

Cela pourrait également être utilisé pour rediriger toute commande, pour un répertoire que 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 est de l'empêcher de sortir aussi vers l'écran pour le garder le même que l'exemple original inventé ci-dessus.

81
répondu Jonathan 2017-11-21 14:23:19

une astuce que j'ai moi-même compris était

sudo ls -hal /root/ | sudo dd of=/root/test.out
66
répondu rhlee 2011-11-21 14:24:03

le problème est que la commande est exécutée sous sudo , mais la redirection est exécutée sous votre utilisateur. Cela se fait par la coque et il ya très peu que vous pouvez faire à ce sujet.

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

L'habitude moyens de contourner ce sont:

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

    Si les commandes et/ou journal les modifications de fichier, vous pouvez faire script les prend comme arguments. Par exemple:

    sudo log_script command /log/file.txt
    
  • appeler un shell et passer la ligne de commande comme paramètre avec -c

    ceci est particulièrement utile pour une commande off compound. Par exemple:

    sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    
39
répondu dsm 2018-03-19 20:05:30

encore une autre variation sur le thème:

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

Ou bien:

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

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

19
répondu Steve Bennett 2013-05-13 07:56:59

d'éclairer un peu sur les raisons de la té option est préférable

en supposant que vous avez la permission appropriée pour exécuter la commande qui crée la sortie, si vous pipez la sortie de votre commande à tee, vous avez seulement besoin d'élever privledges de tee avec sudo et direct tee pour écrire (ou ajouter) au fichier en question.

dans l'exemple donné dans la question qui signifierait:

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

pour un deux autres exemples 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 habituellement accessible en écriture que par root, ce qui est l'origine de votre question.

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

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

16
répondu jg3 2013-11-07 19:16:27

faire courir sudo un shell, comme ceci:

sudo sh -c "echo foo > ~root/out"
15
répondu Penfold 2008-09-17 11:48:32

La façon dont je voudrais aller sur ce problème:

si vous devez écrire/remplacer le fichier:

echo "some text" | sudo tee /path/to/file

si vous devez ajouter au fichier:

echo "some text" | sudo tee -a /path/to/file
6
répondu Nikola Petkanski 2016-06-24 19:48:59

Que Diriez-vous d'écrire un script?

nom du fichier: myscript

#!/bin/sh

/bin/ls -lah /root > /root/test.out

# end script

puis utilisez sudo pour exécuter le script:

sudo ./myscript
5
répondu 2008-09-17 12:25:47

je le ferais de cette façon:

sudo su -c 'ls -hal /root/ > /root/test.out'
4
répondu fardjad 2013-04-21 12:33:10

chaque fois que je dois faire quelque chose comme ça, je deviens racine:

# sudo -s
# ls -hal /root/ > /root/test.out
# exit

ce n'est probablement pas la meilleure façon, mais ça marche.

3
répondu Adam J. Forster 2008-09-17 11:49:12

voici une extension de la réponse impliquant tee. Pour faciliter les choses, vous pourriez faire un petit script (je l'appelle suwrite ou vous pouvez appeler cela de sutee) et le mettre dans /usr/local/bin/ +x permission:

#! /bin/sh
sudo tee $@ > /dev/null

maintenant, tout ce que vous avez à faire est de pipe la sortie à ce script suivi par le superutilisateur-accessible filename et il vous demandera automatiquement votre mot de passe si nécessaire (puisqu'il inclut sudo).

echo test | suwrite /root/test.txt

notez que puisqu'il s'agit d'un simple wrapper pour tee, il acceptera aussi l'option te's-a (ou toute autre) pour ajouter au fichier désiré vous passerez juste-a:

echo test | suwrite -a /root/test.txt
2
répondu jamadagni 2013-11-27 04:55:53

ne signifie pas battre un cheval mort, mais il ya trop de réponses ici qui utilisent tee , ce qui signifie que vous devez rediriger stdout à /dev/null à moins que vous voulez voir une copie sur l'écran. Une solution plus simple est d'utiliser cat comme ceci:

sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"

remarquez comment la redirection est placée entre guillemets pour qu'elle soit évaluée par un shell démarré par sudo au lieu de celui qui l'exécute.

2
répondu haridsv 2016-07-28 09:27:47

peut-être vous a-t-on donné accès à sudo seulement à certains programmes/chemins? Ensuite, il n'y a aucun moyen de faire ce que vous voulez. (sauf si on vous le hack c'est en quelque sorte)

si ce n'est pas le cas, alors peut-être vous pouvez écrire script bash:

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

Appuyez sur ctrl + d :

chmod a+x myscript.sh
sudo myscript.sh

Espère que ça aide.

1
répondu user15453 2013-03-21 11:39:27
sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
0
répondu user8648126 2017-09-21 12:29:23