103 votes

Capturer stdout et stderr dans des variables différentes

Est-il possible de stocker ou de capturer stdout et stderr en différentes variables sans utiliser de fichier temporaire ? Pour l'instant, je fais ceci pour obtenir stdout en out et stderr dans err en cours d'exécution some_command mais je mais j'aimerais éviter le fichier temporaire.

error_file=$(mktemp)
out=$(some_command 2>$error_file)
err=$(< $error_file)
rm $error_file

0voto

Bruce Points 98

Voici une variante plus simple qui n'est pas tout à fait ce que le PO voulait, mais qui ne ressemble à aucune des autres options. Vous pouvez obtenir ce que vous voulez en réorganisant les descripteurs de fichiers.

Commande de test :

%> cat xx.sh  
#!/bin/bash
echo stdout
>&2 echo stderr

ce qui est le cas en soi :

%> ./xx.sh
stdout
stderr

Maintenant, imprimer stdout, capturer stderr vers une variable, et enregistrer stdout dans un fichier

%> export err=$(./xx.sh 3>&1 1>&2 2>&3 >"out")
stdout
%> cat out    
stdout
%> echo
$err 
stderr

Ou enregistrer stdout et capturer stderr dans une variable :

export err=$(./xx.sh 3>&1 1>out 2>&3 )
%> cat out
stdout
%> echo $err
stderr

Vous voyez l'idée.

0voto

Eduardo Cuomo Points 1433

Sortie en temps réel et écriture dans un fichier :

#!/usr/bin/env bash

# File where store the output
log_file=/tmp/out.log

# Empty file
echo > ${log_file}

outToLog() {
  # File where write (first parameter)
  local f="$1"
  # Start file output watcher in background
  tail -f "${f}" &
  # Capture background process PID
  local pid=$!
  # Write "stdin" to file
  cat /dev/stdin >> "${f}"
  # Kill background task
  kill -9 ${pid}
}

(
  # Long execution script example
  echo a
  sleep 1
  echo b >&2
  sleep 1
  echo c >&2
  sleep 1
  echo d
) 2>&1 | outToLog "${log_file}"

# File result
echo '==========='
cat "${log_file}"

0voto

pmarreck Points 11

J'ai posté ma solution à ce problème ici. Elle utilise la substitution de processus et nécessite Bash > v4 mais capture également stdout, stderr et le code de retour dans des variables que vous nommez dans la portée actuelle :

https://gist.github.com/pmarreck/5eacc6482bc19b55b7c2f48b4f1db4e8

Le but de cet exercice était de me permettre d'affirmer ces choses dans une suite de tests. Le fait que je vienne de passer tout l'après-midi à comprendre cette chose qui semble simple... J'espère que l'une de ces solutions aidera d'autres personnes !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X