Comment réutiliser la dernière sortie de la ligne de commande?

43

J'aimerais savoir comment réutiliser la dernière sortie de la console, à savoir:

pv-3:method Xavier$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/Library/Python/2.6/site-packages
pv-3:method Xavier$ cd **LASTOUTPUT**
méthodofaction
la source
7
Vous ne pouvez pas; il y a une explication de fond ici . Votre meilleur choix est de réexécuter la commande, comme indiqué dans les deux réponses publiées jusqu'à présent.
Gilles 'SO- arrête d'être méchant'
Vous ne pouvez pas capturer la sortie envoyée directement à un périphérique tel que /dev/tty, mais il devrait être possible de capturer tout ce qui est envoyé à stdoutou stderrqui pourrait être adéquat.
Mikel
@Gilles - à moins que vous n'utilisiez la réponse de @ mattdm, bien sûr!
simon
@Gilles: mais il pourrait y avoir un shell créé par quelqu'un qui capturera (et passera) les sorties des commandes et rendra les sorties capturées disponibles pour que l'utilisateur puisse s'y référer à partir de ses commandes ultérieures. Peut-être y a-t-il même des coquilles existantes, moins populaires, qui permettent cela avec plus ou moins de complications ...
imz - Ivan Zakharyaschev
1
Duplication possible de l' utilisation du texte des commandes précédentes
Gilles 'SO - arrête d'être méchant'

Réponses:

39

En supposant que bash:

% python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.7/site-packages
% cd $(!!)
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
% pwd
/usr/lib/python2.7/site-packages
jsbillings
la source
1
Merci! Pas trop facile à taper mais ça vaut mieux que d’utiliser la souris.
methodofaction
2
Vous pouvez également utiliser des backticks (je ne vois pas comment rendre cette interface non wikify) au lieu de $ (), mais j'ai constaté qu'il m'est inconfortable de toucher backtick-shift-1-shift-1-backtick et j'essaie de prendre l'habitude d'utiliser $ () lorsque cela est possible pour des raisons de lisibilité.
Jsbillings
@ jsbillings voir ma réponse ci-dessous. J'ai tapé \ `pour afficher` dans la réponse. Et pour afficher '\', tapez comme d'habitude '\\'.
Yasouser
3
+1 Je me suis demandé comment nidifier `backtick-commands`! cd $(dirname $(which python))j'arrive!
Ed Brannin
21
Juste une note, rappelez-vous qu'il s'agit d'une réexécution de la commande. Si votre commande a des effets secondaires, cela ne fonctionnera peut-être pas pour vous.
Rich Homolka
13

Pas encore mentionné, utilisez une variable:

dir=$( python -c ... )
cd "$dir"
Glenn Jackman
la source
3
Exactement. Parce que c'est un shell, les gens oublient souvent les fonctionnalités du langage fournies par Bash, telles que les boucles et les assignations.
Evan
peut simplement direcd $dir
temporaire
3
@Aerovistae, les guillemets sont obligatoires si vous ne savez pas d'où vient la valeur:
glenn jackman le
@glenn, (je sais que cela pourrait être une toute autre question, mais si la réponse est courte :) pourriez-vous expliquer davantage / donner un exemple où l'absence de guillemets briserait les choses?
Alexey
2
L'explication canonique est unix.stackexchange.com/questions/171346/…
glenn jackman
8

Toutes les autres solutions impliquent de modifier votre flux de travail ou d'exécuter la commande deux fois, ce qui peut ne pas convenir si son exécution est longue ou sa répétition impossible (par exemple, il supprime un fichier - son réexécution produirait un résultat différent).

Alors, voici une idée plus compliquée si vous en avez besoin:

.bashrc

exec > >(tee -a ~/$$.out)

PROMPT_COMMAND='LASTLINE=$(tail -n 1 ~/$$.out)'

trap 'rm ~/$$.out' EXIT

invite bash

$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.6/dist-packages
$ cd $LASTLINE
$ pwd
/usr/lib/python2.6/dist-packages

Cela pose quelques problèmes, alors il ne s'agit que d'un point de départ. Par exemple, le fichier de sortie ( ~/<pid>.out) peut devenir très volumineux et remplir votre disque. En outre, toute votre coquille pourrait cesser de fonctionner si elle teemourait.

Il pourrait être modifié pour ne capturer que le résultat de la commande précédente en utilisant preexecet precmdhooks dans zsh, ou une émulation de ceux-ci dans bash, mais c'est plus compliqué à décrire ici.

Mikel
la source
6
L'idée de base est bonne, mais la mise en œuvre ne l'est pas. La sortie standard de la session shell n’est pas un terminal, mais un canal, ce qui entraînera un comportement différent de certains programmes. Il n'y aura pas de synchronisation entre les écritures sur stdout et les écritures sur stderr ou directement sur le terminal, de sorte que, par exemple, la sortie de la commande peut s'afficher après l'invite suivante. Vous n’avez pas non plus protégé teedes signaux (essayez d’appuyer Ctrl+Cet de lancer plusieurs commandes). Utilisez l' scriptutilitaire qui n'a aucun de ces problèmes.
Gilles 'SO- arrête d'être méchant'
Bon à savoir! Je travaille toujours sur les bases de ma ligne de commande, ce qui est peut-être excessif pour moi. De plus, je veux pouvoir l'utiliser sur n'importe quel ordinateur, mais je m'en souviendrai si j'atteins un bon niveau.
methodofaction
8

Un brouillon de travail pour un shell traditionnel:

ttyid=$(readlink /proc/$$/fd/1)
\___/   \______/ \___/ |  |  |
  |         |      |   |  |  \- 0: stdin 
  |         |      |   |  |     1: stdout <- our interest
  |         |      |   |  |     2: stderr
  |         |      |   |  \- fd is, maybe, filedescriptor
  |         |      |   |
  |         |      |   \- $$ is the PID of the current process (shell,
  |         |      |      in our case)
  |         |      |
  |         |      \- you know, much runtime stuff is here
  |         |
  |         \- readlink extracts the symbolic link of /proc/$$/fd/1
  |            lrwx------ 1 stefan stefan 64 2011-03-18 09:11
  |            /proc/22159/fd/1 -> /dev/pts/4
  |
  \- /dev/tty3 for real shell, /dev/pts/3 for xterm

Nous pouvons maintenant afficher l’écran dans un fichier. Besoin de sudo.

id=${ttyid//\/dev\/tty}
sudo cat /dev/vcs$id > screen.dump

Apropos screendump: le programme ainsi nommé ne fonctionne plus pour moi. Peut-être pour les noyaux plus âgés seulement. / dev / pts / N n'a pas fonctionné pour moi aussi. Vous avez peut-être besoin de quelques MKDEV optionnels dans / dev - je me souviens très mal de certains /dev/cuaN, mais je peux me tromper.

Nous aimerions diriger la sortie au lieu d'utiliser screen.dump. Mais de toute façon, cela ne fonctionne pas - parfois, il attend ENTER.

La capture n'est pas un fichier texte normal avec des sauts de ligne, mais avec, par exemple, 80 x 50 caractères dans une séquence.

Pour choisir les 2 dernières lignes, 1 pour la sortie de la commande et une pour la ligne d'invite, je l'inverse, je choisis 160 caractères, je reviens à nouveau et nous choisissons 80.

rev vcs4.dat | sed 's/\(.\{160\}\).*/\1/g' | rev | sed 's/\(.\{80\}\).*/\1/g'

Juste au cas où vous vous seriez déjà demandé pourquoi il y avait un revprogramme.

La critique:

  • Les premières commandes sont entrées, déplaçant ainsi la ligne ahed. Eh bien - juste un exercice numérique pour choisir la 3ème dernière ligne ou quelque chose. J'ai travaillé principalement dans une fenêtre différente.
  • Tout le monde n'a pas d'écran 80x50. Eh bien, oui, nous savons. Il y a $ COLUMNS et $ ROWS pour votre plaisir.
  • La sortie n'est pas toujours au bas. Une coquille fraîche et jeune pourrait être dans les rangées supérieures. Bien - aussi simple que cela: Évaluez quel shell est en cours d’exécution. Quelle invite est utilisée. Effectuez une détection rapide et recherchez la dernière ligne avec une invite du shell. La ligne avant (ou 2. avant) doit contenir le répertoire.

Le premier diagramme est fait avec explique.py

Utilisateur inconnu
la source
+1, m'a fait fairealias tee2tty='tee $(readlink /proc/$$/fd/1)'
Tobias Kienzler
7

Essaye ça:

$ cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
$ pwd
/Library/Python/2.6/site-packages
bahamat
la source
6

Alors, voici une réponse:

Si vous utilisez X, sélectionnez le résultat souhaité avec la souris pour le copier, puis cliquez avec le bouton du milieu pour le coller.

Si vous utilisez une console texte, vous pouvez faire la même chose avec gpm .

mattdm
la source
1
+1 - bonne réponse! vous pouvez obtenir le même résultat, même si vous n’utilisez pas X, en utilisant l’écran GNU ( gnu.org/software/screen ).
simon
1
Cela semblait tellement évident que j’étais hésitant à le dire. Mais tout le monde est tellement occupé à être intelligent. :)
Mattdm
c’est la seule réponse possible qui permet à l’opérateur de réutiliser la dernière ligne - tout le reste implique de réexécuter la commande, ce qui peut être n'importe où entre totalement inutile et catastrophique :) Mais l’opérateur a dit réutilisation .
simon
@ simon: En fait, ma réponse n'est pas. Glenn non plus.
Mikel
@ Mikel: C'est vrai, mais ils exigent que vous fassiez quelque chose à l'avance ou correctement la première fois.
Mattdm
1

(Malheureusement, ce n’est pas une réponse satisfaisante, mais il ya toujours quelque chose de curieux. Une personne intéressée pourrait bien essayer de terminer la mise en oeuvre de la fonctionnalité dont je vais vous parler.)

À l' eshellintérieur d'Emacs, ils souhaitaient une telle fonctionnalité, mais celle-ci n'est pas implémentée de manière complète (ce qui est toutefois reflété dans la documentation ).

Par exemple:

~ $ pwd
~
~ $ /bin/echo $$
~
~ $ /bin/pwd
/home/imz
~ $ /bin/echo $$

~ $ 

Vous voyez, seule la sortie des commandes intégrées peut être capturée dans la $$variable.

Mais bon, une certaine programmation elisp (cf. eshell-mark-outputimplémentation dans "esh-mode.el"), et vous pourriez implémenter une fonction qui "marque" la dernière sortie et la renvoie comme résultat; afin que vous puissiez utiliser cette fonction dans une commande eshell que vous demandez - les fonctions elisp peuvent être utilisées dans des commandes eshell avec la syntaxe elisp habituelle, c'est-à-dire entre parenthèses, comme ceci:

~ $ /bin/echo (buffer-name)
*eshell*
~ $ /bin/echo (car '(a b c))
a
~ $ 
imz - Ivan Zakharyaschev
la source
0

Si vous réalisez que vous souhaitez réutiliser la sortie avant de frapper Enter, vous pouvez l'enregistrer dans une variable: ajoutez tmp=$(au début de la ligne et )à la fin. (Cela supprime toute ligne vide à la fin de la sortie de la commande et supprime en fait toute nouvelle ligne; ceci importe rarement.)

tmp=$(python -c )
echo "$tmp"
cd "$tmp"

Si votre shell est ksh ou zsh, voici une fonction utile que vous pouvez utiliser pour rendre cela plus automatique. (Ce n'est pas une aide dans bash car il nécessite que la dernière commande d'un pipeline soit exécutée dans le shell parent, ce qui n'est le cas que dans ksh (pas pdksh) et zsh.)

keep () {
  local line IFS=$'\n'
  kept=
  while read -r line; do
    printf '%s\n' "$line"
    kept=$kept$line$IFS
  done
}
alias keep=k

Utilisez-le de cette façon:

python -c  |k
cd $kept
Gilles, arrête de faire le mal
la source
0
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" | tee $(readlink /proc/$$/fd/1))

(s'appuyant sur la réponse de 4485 )

C'est beaucoup de dactylographie, alors faites un alias:

alias tee2tty='tee $(readlink /proc/$$/fd/1)'

Ensuite, appelez simplement cd $(python -c ... | tee2tty)

Bien entendu, cela nécessite que vous sachiez déjà ce que vous voulez faire avec la sortie, mais présente l'avantage d'appeler la commande une seule fois.

Tobias Kienzler
la source
0
$ cd \`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"\`

fera l'affaire.

Lisez ici pour plus de détails: Substitution de commande .

Yasouser
la source
1
arumug: bahamat a déjà posté presque la même réponse . Votre version avec backticks ne fonctionnera pas toujours s'il y a déjà des backticks dans la commande.
Gilles 'SO- arrête d'être méchant'
0

Il y a une meilleure solution:

Imprimez juste !!après la commande exécutée et vous obtiendrez une sortie répétée.

Par exemple

entrez la description de l'image ici

Original:

https://askubuntu.com/questions/324423/how-to-access-the-last-return-value-in-bash

Tebe
la source
!!ne répète pas le résultat de la dernière commande, il réexécute la dernière commande. Si jot -r 1 0 1000retourne un seul nombre aléatoire entre 0 et 1000, après avoir exécuté cette commande une fois et en obtenant 539, l'exécution !!donnera probablement un autre nombre. !!peut également être indésirable si la commande précédente prend beaucoup de temps à exécuter ou répète une opération qui ne devrait pas être répétée (comme changer un fichier).
Caleb
1
Belle prise. Bien qu'il existe un moyen plus facile de me prouver le contraire: echo $ RANDOM; !!
Tebe
Sweet - ne savait pas à ce sujet! Merci.
Caleb