web-dev-qa-db-fra.com

Réutilisation des résultats de la dernière commande dans Bash

La sortie d'une commande Bash est-elle stockée dans un registre? Par exemple. quelque chose de similaire à $? capturant la sortie au lieu du statut de sortie.

Je pourrais assigner la sortie à une variable avec: 

output=$(command)

mais c'est plus taper ... 

112
memecs

Vous pouvez utiliser ceci: $(!!)to pour recalculer (ne pas réutiliser) le résultat de la dernière commande.

Le !! à lui seul exécute la dernière commande.

$ > echo pierre
pierre
$ > echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
123
ling

La réponse est non. Bash n'alloue aucune sortie à aucun paramètre ni à aucun bloc de sa mémoire. De plus, vous n'êtes autorisé à accéder à Bash que par ses opérations d'interface autorisées. Les données privées de Bash ne sont accessibles que si vous les piratez.

67
konsolebox

Une façon de faire est d'utiliser trap DEBUG:

f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG

Les commandes stdout et stderr de la dernière commande exécutée seront maintenant disponibles dans /tmp/out.log

Le seul inconvénient est qu'il exécutera une commande deux fois: une fois pour rediriger la sortie et une erreur à /tmp/out.log et une fois normalement. Il existe probablement un moyen d’empêcher ce comportement également.

8
anubhava

Inspiré par la réponse d’anubhava, qui, à mon avis, n’est pas acceptable dans la mesure où chaque commande est exécutée deux fois.

save_output() { 
   exec 1>&3 
   { [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
   exec > >(tee /tmp/current)
}

exec 3>&1
trap save_output DEBUG

De cette façon, la sortie de la dernière commande est dans/tmp/last et la commande n'est pas appelée deux fois.

3
olivecoder

Si vous êtes sur mac et que cela ne vous dérange pas de stocker votre sortie dans le presse-papiers au lieu d'écrire dans une variable, vous pouvez utiliser pbcopy et pbpaste comme solution de contournement.

Par exemple, au lieu de cela, recherchez un fichier et différez son contenu avec un autre fichier:

$ find app -name 'one.php' 
/var/bar/app/one.php

$ diff /var/bar/app/one.php /var/bar/two.php

Vous pourriez faire ceci:

$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php

La chaîne /var/bar/app/one.php est dans le Presse-papiers lorsque vous exécutez la première commande. 

Soit dit en passant, pb dans pbcopy et pbpaste signifient «pâte à papier», synonyme de «presse-papiers». 

3
Raghu Dodda

Comme dit konsolebox, il vous faudrait pirater lui-même. Ici est un très bon exemple de la façon dont on pourrait y parvenir. Le référentiel stderred (en réalité destiné à la coloration de stdout) donne des instructions sur la façon de le construire.

J'ai essayé: Définir un nouveau descripteur de fichier dans .bashrc comme

exec 41>/tmp/my_console_log

(nombre est arbitraire) et modifiez stderred.c en conséquence de sorte que le contenu soit également écrit dans le dossier 41. Il un genre de a fonctionné, mais contient des charges d'octets NUL, de formatages étranges et constitue essentiellement des données binaires, non lisibles. Peut-être que quelqu'un avec une bonne compréhension de C pourrait essayer cela.

Si c'est le cas, tout ce qui est nécessaire pour obtenir la dernière ligne imprimée est tail -n 1 [logfile]

1
Blauhirn

J'ai une idée que je n'ai pas le temps d'essayer de mettre en œuvre immédiatement. 

Mais que faire si vous faites quelque chose comme ceci: 

$ MY_HISTORY_FILE = `get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1 | tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!

Il pourrait y avoir des problèmes avec la mise en mémoire tampon de IO. En outre, le fichier peut devenir trop volumineux. Il faudrait trouver une solution à ces problèmes. 

0
William Navarre

Vous ne savez pas exactement pourquoi vous avez besoin de cela, alors cette réponse peut ne pas être pertinente. Vous pouvez toujours sauvegarder le résultat d'une commande: netstat >> output.txt, mais je ne pense pas que ce soit ce que vous cherchez.

Il y a bien sûr des options de programmation cependant; vous pouvez simplement demander à un programme de lire le fichier texte ci-dessus une fois la commande exécutée et de l'associer à une variable. Dans Ruby, ma langue de choix, vous pouvez créer une variable en sortie de commande à l'aide de 'backticks': 

output = `ls`                       #(this is a comment) create variable out of command

if output.include? "Downloads"      #if statement to see if command includes 'Downloads' folder
print "there appears to be a folder named downloads in this directory."
else
print "there is no directory called downloads in this file."
end

Collez ceci dans un fichier .rb et exécutez-le: Ruby file.rb. Il créera une variable en dehors de la commande et vous permettra de le manipuler. 

0
user4493605