Comment puis-je utiliser sudo dans une fonction?

J'ai écrit une fonction qui agit de la même façon que le tee mais qui pré-pend un datestamp. tout fonctionne bien, sauf quand je veux sortir dans un file qui est seulement root writeable (dans mon cas un file journal dans /var/log ). j'ai simplifié l'extrait de code suivant pour simplement inclure les bits qui ne fonctionnent pas:

 #!/bin/bash #script ~/test_logger.sh logfile=/var/log/test.log logger() { while read data do echo $data >> $logfile done return 0 } sudo ls ~ | logger 

cela fonctionne bien si je cours tout le script comme sudo ~/test_logger.sh mais je ne peux pas toujours le faire puisque je veux utiliser la fonction logger dans des files comme ~/.bash_logout qui sont exécutés automatiquement. J'ai essayé de mettre sudo devant l'écho dans la boucle while mais cela ne fonctionne pas. des idées?

c'est généralement une mauvaise habitude de mettre sudo dans un script. Un meilleur choix serait d'appeler le script avec sudo partir de ~/.bash_logout ou de l'endroit où vous voulez l'utiliser, si vous le souhaitez, ou mieux encore, faites simplement /var/log/test.log écriture dans le monde.

comme vous l'avez trouvé, la sudo command >out ne fonctionne pas car la command 'sudo' est exécutée par sudo, mais '> out' est une fonction du shell et non de 'command'. Donc, vous devez escalader la shell elle-même:

 sudo sh -c "echo $data >>$logfile" 

notez que vous voulez être vraiment, vraiment sûr de ce qui se passe dans $ data:

 ~$ export data='good; touch /tmp/reallybad' ~$ echo $data good; touch /tmp/reallybad ~$ sudo sh -c "echo $data>>/tmp/happy" good ~$ ls /tmp/happy /tmp/reallybad /tmp/happy /tmp/reallybad 

d'où l'avertissement de Simon.

sudo ne fonctionne pas comme vous le pensez lorsque vous utilisez des opérateurs de redirection ou de pipe. Le changement de stream n'est pas exécuté avec les permissions sudo . C'est pourquoi

 sudo echo foo >> bar 

ne fonctionnera pas si la barre est seulement root-inscriptible.

Lorsque vous exécutez le script sous sudo , tout dans le script obtient les permissions super-user afin qu'il fonctionne correctement dans cette circonstance.

Une solution de contournement consiste à faire en sorte que la command d'écriture s'exécute sous sudo :

 sudo echo foo | sudo tee bar > /dev/null 

Gardez à l'esprit, cependant, que cela n'ajoute pas au file. Il écrase le file.

Eh bien, si vous jetez un oeil à la page man de sudo, vous pouvez voir des exemples de comment l'utiliser dans les scripts … l'option -c permet d'exécuter une command.

Vous ne tapez que la command ls , mais pas logger . Bash ne sait pas (et ne devrait pas) savoir ce que fait sudo , donc il ne fait que canaliser deux commands. Le premier est sudo et le second est logger . Peu importe si vous sudo ls , l' logger ne sera pas.

Vous devriez sudo logger , mais cela ne fonctionnera pas car il s'agit d'une fonction Bash au lieu d'un exécutable à exécuter par sudo .

ATTENTION : ls | sudo logger ls | sudo logger /usr/bin/logger s'il est installé sur votre système. Rappelez-vous: sudo ne connaît pas les fonctions Bash.

Je vous suggère d'append l'user invoquant votre script au groupe du propriétaire du file afin que vous puissiez écrire sans escalade de privilèges spéciaux.

De plus, l'efficacité, vous ouvrez et fermez le file journal pour chaque ligne lue. Vous ne pouvez le faire qu'une seule fois pour l'set du process de journalisation:

 function logger() { while read data do echo "$data" done return 0 } >>"$logfile"