Bonjour,
petite question sur la redirection de script :
j'aimerai savoir (la cible c'est en bash, mais si en vous connaissez qui marche sous d'autres shells, pourquoi pas ?) comment faire une commande en début de mes scripts qui :
- envoie la sortie standard vers std_out.log
- envoie la sortie erreur (et toutes les autres, au cas ou) vers std_err.log
- si le terminal est interactif, affiche aussi à l'écran les deux sorties, sinon, n'affiche rien. (dans le cas des taches cron, par exemple)
les noms des fichiers sont juste pour l'exemple, bien sur. En fait, ils seraient remis à zero au debut de chaque script (avec un avertissement) ou nommés avec une date, bref, peu importe.
bon, pour l'instant je me bats avec exec, qui donne des résultats mitigés. Par exemple,
if ["${PS1}" ] ; then
exec 2> err.log > out.log
else
???
fi
fait ce qu'il faut. Mais reste le problème de la redirection en même temps vers le terminal et deux fichiers. J'ai essayé des douzaines de combinaisons, d'abord en lisant le manuel, puis un peu au hasard, (sait-on jamais :) mais je n'ai pas trouvé la solution...
Si quelqu'un a une idée...
Par contre, je signale un bon guide, Advanced Bash-Scripting Guide, sur TLDP,
http://www.tldp.org/LDP/abs/html/(...)
PS: j'ai beau visualiser, le caractère de redirection ne s'affiche pas très bien. pour info le " & gt ; " signifie superieur, pour ceusses qu'auraient du mal :)
# Take a cup of tee
Posté par yannig (site web personnel) . Évalué à 2.
Le programme que tu recherches s'appelle tee. Pour rediriger la sortie d'un programme tout en l'affichant :
echo toto | tee /tmp/log
Par contre pour rediriger la sortie d'erreur vers autre chose ... j'ai pas trop d'idée.
Bonne chance !
[^] # Re: Take a cup of tee
Posté par totof2000 . Évalué à 1.
Il faut juste verifier que la commande who -m te retourne ceci (le deuxieme champ est interessant):
totof2000 pts/4 02 ao{ 15:24
#!/bin/ksh
# Identification du pseudo-terminal de sortie
SORTIE=/dev/$( who -m |awk '{ print $2}')
echo $SORTIE
# Commande:
(ls - toto | tee titi.log>$SORTIE)2>&1 | tee error.log
Tu mets tout ca dans un script test1.ksh (ou test1.sh, peu importe).
A l'exécution:
$ksh test1.ksh
/dev/pts/4
ls : 0653-341 Le fichier - n'existe pas.
ls : 0653-341 Le fichier toto n'existe pas.
$more titi.log
$more error.log
ls : 0653-341 Le fichier - n'existe pas.
ls : 0653-341 Le fichier toto n'existe pas.
$
$touch toto
$ksh test1.ksh
/dev/pts/4
toto
ls : 0653-341 Le fichier - n'existe pas.
$more titi.log
toto
$more error.log
ls : 0653-341 Le fichier - n'existe pas.
Normalement, en cron, le pseudo-terminal devrait être /dev/null (a verifier).
[^] # Re: Take a cup of tee
Posté par Valdenaire Denis (site web personnel) . Évalué à 1.
Justement, je veux éviter d'avoir à lancer les commandes shell comme ça :
./script.sh 2>&1 | tee script.log
Mais ça me donne une idée ...
En fait il faudrait dupliquer les file descriptors out (1) et err(2) comme le ferait un tee, afficher le 1 et le 2 à l'écran, et diriger les duplicats vers deux fichiers...
je vais finir par trouver :) je sens que je suis pas loin !
[^] # Re: Take a cup of tee
Posté par totof2000 . Évalué à 1.
[^] # Re: Take a cup of tee
Posté par totof2000 . Évalué à 1.
Si elle échoue, SORTIE=/dev/null
[^] # Re: Take a cup of tee
Posté par totof2000 . Évalué à 1.
J'ai pas de linux sous la main, peux-tu me dire si who -m fonctionne comme sous aix ?
#!/bin/ksh
# Identification du pseudo-terminal de sortie
SORTIE=/dev/$((who -m 2>/dev/null || echo "toto null") |awk '{ print $2}')
echo $SORTIE
myexec() {
# Commande:
($* | tee titi.log>$SORTIE)2>&1 | tee error.log >$SORTIE
}
myexec ls - toto
[^] # Re: Take a cup of tee
Posté par totof2000 . Évalué à 1.
# est-ce que perl est un shell ?
Posté par gc (site web personnel) . Évalué à 2.
open STDOUT, "|tee stdout";
open STDERR, "|tee stderr >&2";
et puis même que si tu es vraiment masochiste et que tu veux quand même utiliser bash ça te donnera une idée poir réussir à le faire en bash.
# Une solution en Shell
Posté par CoinKoin . Évalué à 1.
$> mkfifo mon_pipe
$> ma_commande 2>mon_pipe | tee out.log &
$> cat mon_pipe | tee err.log
Sans oublier de faire :
$> rm mon_pipe
à la fin de la manipulation.
# pas évident
Posté par tgl . Évalué à 2.
http://tdegreni.free.fr/files/foobar.sh(...)
Le problème qui persiste est que stdout et stderr ne sont pas synchronisés, et que donc des messages rapidement enchainés sur chacune de ses sorties peuvent se retrouver entrelacés sur le terminal. En fait, je ne vois pas vraiment de solution à ce problème : la duplication des deux flux passe forcement par des processus concurrents (les deux 'tee'), qui sont bufferisés, et on n'a pas le contrôle de leur ordonnancement. Peux être qu'en C on pourrait faire un seul processus pour consommer et dupliquer les deux flux alternativement (et vu que côté producteur l'écriture sur des pipes est bloquante, on ne perdrait pas la synchro), bref on pourrait faire un genre de double-tee, mais en shell par contre je ne vois vraiment pas.
À part ça, tu verras que dans mon script je n'ai pas distingué shell interactif de shell non-interactif. Il me semble d'ailleurs que tout ce qui est mis dans un script est non-interactif, sauf à forcer ça avec un "#!/bin/bash -i". Je ne crois pas que ton test sur $PS1 fonctionne comme tu l'attends, parceque $PS1 n'est pas censé être exporter. Moi en général, quand je veux appeler qqch depuis un cron sans pourrir mon log, je ne compte pas sur le script lui même, mais je fais mon appel avec "&>/dev/null", et puis voilà.
Bon ceci dit, si tu tiens à tester ça au niveau du script, alors y'a peut être moyen plutôt avec $TERM, ou encore avec la commande 'tty', je sais pas trop... Je sais qu'en python par exemple, je ferais ça avec le prédicat "sys.stdout.isatty()", mais en bash, j'ai jamais essayer de trouver un équivalent. Si tu trouves, alors dans mon script ce sera facile de rajouter le test pour faire un appel récursif avec une redirection plus simple dans le cas non-interactif (genre '$0 "${@}" 1>${STDOUT_LOG} 2>${STDERR_LOG}').
[^] # Re: pas évident
Posté par tgl . Évalué à 2.
[^] # Re: pas évident
Posté par tgl . Évalué à 2.
http://tdegreni.free.fr/files/foobar2.sh(...)
# QQ chose très crade comme ça ?
Posté par Florent Bayle (site web personnel) . Évalué à 1.
echo -n > err.log
tail -f out.log &
tail -f err.log &
ls > out.log >& err.log && sleep 1
killall tail
C'est très crade...
Remplacer killall tail pas qq chose de moins... destructif serait une bonne idée, mais j'ai pas trop le temps, je vous livre juste ça comme ça pour vous donner des idée...
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.