J’écris un script pour sauvegarder une firebase database. J’ai la ligne suivante:
mysqldump --user=$dbuser --password=$dbpswd \ --host=$host $mysqldb | gzip > $filename
Je veux assigner le stderr à une variable, de manière à ce qu’il m’envoie un email pour me faire savoir ce qui s’est passé si quelque chose ne va pas. J’ai trouvé des solutions pour redirect stderr vers stdout, mais je ne peux pas le faire car la sortie standard est déjà envoyée (via gzip) dans un fichier. Comment puis-je stocker stderr séparément dans une variable $ result?
Essayez de redirect stderr vers stdout et utilisez $()
pour capturer cela. En d’autres termes:
VAR=$((your-command-including-redirect) 2>&1)
Comme votre commande redirige quelque part la sortie standard, elle ne devrait pas interférer avec stderr. Il pourrait y avoir une façon plus propre de l’écrire, mais cela devrait fonctionner.
Modifier:
Cela fonctionne vraiment. Je l’ai testé:
#!/bin/bash BLAH=$(( ( echo out >&1 echo err >&2 ) 1>log ) 2>&1) echo "BLAH=$BLAH"
va imprimer BLAH=err
et le fichier log
contient.
Pour toute commande générique dans Bash, vous pouvez faire quelque chose comme ceci:
{ error=$(command 2>&1 1>&$out); } {out}>&1
La sortie normale apparaît normalement, tout ce qui est stderr est capturé dans $ error (citez-le comme “$ error” lorsque vous l’utilisez pour conserver les nouvelles lignes). Pour capturer stdout dans un fichier, ajoutez simplement une redirection à la fin, par exemple:
{ error=$(ls /etc/passwd /etc/bad 2>&1 1>&$out); } {out}>&1 >output
Briser, lire de l’extérieur, ça:
Vous pouvez enregistrer la référence stdout avant qu’elle ne soit redirigée dans un autre numéro de fichier (par exemple 3), puis redirect stderr vers celui-ci:
result=$(mysqldump --user=$dbuser --password=$dbpswd \ --host=$host $mysqldb 3>&1 2>&3 | gzip > $filename)
Donc, 3>&1
redirecta le fichier numéro 3 vers stdout (notez que c’est avant que stdout ne soit redirigé avec le tube). Ensuite, 2>&3
redirige stderr vers le fichier numéro 3, qui est maintenant identique à stdout. Finalement, stdout est redirigé en étant introduit dans un tube, mais cela n’affecte pas les numéros de fichiers 2 et 3 (notez que la redirection de stdout depuis gzip n’est pas liée aux sorties de la commande mysqldump).
Edit: Mise à jour de la commande pour redirect stderr depuis la commande mysqldump
et non pas gzip
, j’étais trop rapide dans ma première réponse.
dd
écrit à la fois stdout et stderr:
$ dd if=/dev/zero count=50 > /dev/null 50+0 records in 50+0 records out
les deux stream sont indépendants et redirigeables séparément:
$ dd if=/dev/zero count=50 2> countfile | wc -c 25600 $ cat countfile 50+0 records in 50+0 records out $ mail -s "countfile for you" thornate < countfile
si vous aviez vraiment besoin d'une variable:
$ variable=`cat countfile`