Pour le bénéfice du lecteur voici une solution utilisant tempfile
s.
La question n'était pas d'utiliser tempfile
s. Cependant, cela peut être dû à la pollution indésirable de l'eau. /tmp/
avec tempfile au cas où le shell meurt. En cas de kill -9
un peu de trap 'rm "$tmpfile1" "$tmpfile2"' 0
ne fait pas feu.
Si vous êtes dans une situation où vous pouvez utiliser tempfile
mais je veux ne laissez jamais de débris derrière vous voici une recette.
Encore une fois, il est appelé catch()
(comme mon autre réponse ) et possède la même syntaxe d'appel :
catch stdout stderr command args..
# Wrappers to avoid polluting the current shell's environment with variables
: catch_read returncode FD variable
catch_read()
{
eval "$3=\"\`cat <&$2\`\"";
# You can use read instead to skip some fork()s.
# However read stops at the first NUL byte,
# also does no \n removal and needs bash 3 or above:
#IFS='' read -ru$2 -d '' "$3";
return $1;
}
: catch_1 tempfile variable comand args..
catch_1()
{
{
rm -f "$1";
"${@:3}" 66<&-;
catch_read $? 66 "$2";
} 2>&1 >"$1" 66<"$1";
}
: catch stdout stderr command args..
catch()
{
catch_1 "`tempfile`" "${2:-stderr}" catch_1 "`tempfile`" "${1:-stdout}" "${@:3}";
}
Ce qu'il fait :
-
Il crée deux tempfile
pour stdout
y stderr
. Cependant, il les supprime presque immédiatement, de sorte qu'ils ne sont présents que pendant un temps très court.
-
catch_1()
attrape stdout
(FD 1) dans une variable et déplace stderr
a stdout
de sorte que le prochain ("gauche") catch_1
peut attraper ça.
-
Traitement dans catch
se fait de droite à gauche, donc la gauche catch_1
est exécuté en dernier et attrape stderr
.
Le pire qui puisse arriver, c'est que certains fichiers temporaires s'affichent sur /tmp/
mais ils sont toujours vides dans ce cas. (Ils sont supprimés avant d'être remplis). En général, cela ne devrait pas être un problème, car sous Linux, tmpfs supporte environ 128K fichiers par Go de mémoire principale.
-
La commande donnée peut accéder à toutes les variables locales du shell et les modifier. Vous pouvez donc appeler une fonction shell qui a des effets secondaires !
-
Cela ne fait que bifurquer deux fois pour le tempfile
appeler.
Bugs :
-
Manque une bonne gestion des erreurs en cas tempfile
échoue.
-
Cela fait l'habituel \n
le retrait de la coquille. Voir le commentaire dans catch_read()
.
-
Vous ne pouvez pas utiliser le descripteur de fichier 66
pour envoyer des données à votre commande. Si vous en avez besoin, utilisez un autre descripteur pour la redirection, par exemple 42
(Notez que les coquilles très anciennes n'offrent que des FD jusqu'à 9).
-
Il ne peut pas gérer les octets NUL ( $'\0'
) en stdout
y stderr
. (NUL est simplement ignoré. Pour le read
variante tout ce qui se trouve derrière un NUL est ignoré).
FYI :
- Unix nous permet d'accéder aux fichiers supprimés, à condition que vous conserviez une référence à ces fichiers (par exemple, une poignée de fichier ouverte). De cette façon, nous pouvons les ouvrir puis les supprimer.