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"