Wie verwende ich die letzte Ausgabe von der Befehlszeile?


43

Ich möchte wissen, wie ich die letzte Ausgabe von der Konsole wiederverwenden kann:

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**

7
Sie können nicht; gibt es einige Hintergrund Erklärung hier . Am besten führen Sie den Befehl erneut aus, wie in den beiden bisher veröffentlichten Antworten gezeigt.
Gilles 'SO - hör auf böse zu sein'

Sie können keine Ausgabe erfassen, die direkt an ein Gerät wie z. B. gesendet /dev/ttywurde. Es sollte jedoch möglich sein, alle an stdoutoder gesendeten Daten zu erfassen stderr, die möglicherweise ausreichend sind.
Mikel

@ Gilles - es sei denn, Sie verwenden die Antwort von @ mattdm, natürlich!
Simon

@Gilles: Es kann jedoch eine Shell geben, die von jemandem erstellt wurde, der die Ausgaben der Befehle erfasst (und durchläuft) und die erfassten Ausgaben dem Benutzer zur Verfügung stellt, auf die er in seinen weiteren Befehlen verweisen kann. Vielleicht gibt es sogar einige existierende, nicht so beliebte Muscheln, die dies mit mehr oder weniger Komplikationen ermöglichen ...
imz - Ivan Zakharyaschev

Antworten:


39

Vorausgesetzt, 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

1
Vielen Dank! Nicht so einfach zu tippen, aber es ist besser als mit der Maus.
Methodofaction

2
Sie können statt $ () auch Backticks verwenden (ich kann nicht herausfinden, wie dieses Interface nicht wikify wird), aber ich habe festgestellt, dass es für mich unangenehm ist, Backtick-Shift-1-Shift-1-Backtick zu drücken und ich versuche, es mir zur besseren Lesbarkeit zur Gewohnheit zu machen, wenn möglich $ () zu verwenden.
Jsbillings

@ jsbillings siehe meine Antwort unten. Ich habe in die Antwort \ `to display` eingegeben. Und um '\' anzuzeigen, geben Sie wie gewohnt '\\' ein.
Yasouser

3
+1 Ich habe mich gefragt, wie ich nisten soll `backtick-commands`! cd $(dirname $(which python))Hier komme ich!
Ed Brannin

21
Nur eine Anmerkung, denken Sie daran, dass dies den Befehl erneut ausführt. Wenn Ihr Befehl Nebenwirkungen hat, funktioniert dies möglicherweise nicht für Sie.
Rich Homolka

13

Noch nicht erwähnt, benutze eine Variable:

dir=$( python -c ... )
cd "$dir"

3
Genau. Da es sich um eine Shell handelt, vergessen die Benutzer häufig die Sprachfunktionen, die Bash bietet, wie z. B. Schleifen und Zuweisungen.
Evan

kann nur sagencd $dir
temporary_user_name

3
@ Aerovistae, die Anführungszeichen sind erforderlich, wenn Sie nicht wissen, woher der Wert stammt:
Glenn Jackman

@glenn, (Ich weiß, das könnte eine ganz andere Frage sein, aber wenn die Antwort kurz ist :) Könntest du mehr erklären / ein Beispiel liefern, bei dem die Nichtverwendung von Anführungszeichen die Sache kaputt macht?
Alexey


8

Bei allen anderen Lösungen müssen Sie Ihren Workflow ändern oder den Befehl zweimal ausführen. Dies ist möglicherweise nicht geeignet, wenn die Ausführung lange dauert oder nicht wiederholt werden kann (z. B. wenn eine Datei gelöscht wird und ein erneutes Ausführen zu einem anderen Ergebnis führt).

Hier ist eine etwas kompliziertere Idee, wenn Sie sie brauchen:

.bashrc

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

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

trap 'rm ~/$$.out' EXIT

Bash-Eingabeaufforderung

$ 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

Dies hat einige Probleme, so ist es nur als Ausgangspunkt gedacht. Beispielsweise kann die Ausgabedatei ( ~/<pid>.out) sehr groß werden und Ihre Festplatte füllen. Außerdem könnte Ihre gesamte Shell aufhören zu funktionieren, wenn teedies der Fall ist.

Es könnte geändert werden, um nur die Ausgabe des vorherigen Befehls mit preexecund precmdhooks in zsh oder eine Emulation davon in bash zu erfassen , aber das ist hier komplizierter zu beschreiben.


6
Die Grundidee ist gut, die Umsetzung jedoch nicht. Die Standardausgabe in der Shell-Sitzung ist kein Terminal, sondern eine Pipe, wodurch sich einige Programme anders verhalten. Es findet keine Synchronisation zwischen den Schreibvorgängen in stdout und stderr oder direkt in tty statt, sodass beispielsweise die Befehlsausgabe nach der nächsten Eingabeaufforderung angezeigt wird. Sie haben auch nicht vor teeSignalen geschützt (versuchen Sie Ctrl+C, einige Befehle zu drücken und auszuführen). Verwenden Sie das scriptDienstprogramm, bei dem keines dieser Probleme auftritt.
Gilles 'SO - hör auf böse zu sein'

Gut zu wissen! Ich arbeite immer noch an den Grundlagen der Befehlszeile, daher ist dies möglicherweise ein Overkill für mich. Außerdem möchte ich sie auf jedem Computer verwenden können, aber ich werde mich daran erinnern, wenn ich jemals ein gutes Niveau erreiche.
Methodofaction

8

Ein Arbeitsentwurf für eine traditionelle Muschel:

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

Jetzt können wir den Bildschirm in eine Datei umwandeln. Braucht Sudo.

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

Apropos screendump: Das so genannte Programm funktioniert bei mir nicht mehr. Möglicherweise nur für ältere Kernel. / dev / pts / N hat auch bei mir nicht funktioniert. Möglicherweise müssen Sie einige optionale MKDEV in / dev - Ich erinnere mich dunkel über einige /dev/cuaN, aber ich kann falsch sein.

Wir möchten die Ausgabe weiterleiten, anstatt screen.dump zu verwenden. Aber irgendwie funktioniert es nicht - manchmal wartet es auf ENTER.

Das Capturing ist keine normale Textdatei mit Zeilenumbrüchen, sondern mit beispielsweise 80x50 Zeichen in einer Sequenz.

Um die letzten 2 Zeilen auszuwählen, eine für die Ausgabe des Befehls und eine für die Eingabezeile, mache ich es rückgängig, wähle 160 Zeichen, wieder rückgängig und wähle 80.

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

Nur für den Fall, dass Sie sich jemals gefragt haben, warum es ein revProgramm gibt.

Kritik:

  • Die ersten Befehle werden eingegeben, wodurch die Linie verschoben wird. Nun - nur eine numerische Übung, um die drittletzte Zeile auszuwählen oder so. Ich habe hauptsächlich in einem anderen Fenster gearbeitet.
  • Nicht jeder hat einen 80x50-Bildschirm. Nun ja, wir wissen es. Es gibt $ COLUMNS und $ ROWS für Ihr Vergnügen.
  • Die Ausgabe erfolgt nicht immer ganz unten. Eine frische und junge Schale könnte sich in den oberen Reihen befinden. Ganz einfach: Bewerten Sie, welche Shell ausgeführt wird. Welche Eingabeaufforderung wird verwendet? Führen Sie eine schnelle Erkennung durch und suchen Sie die letzte Zeile mit einer Shell-Eingabeaufforderung. Die Zeile vor (oder 2. vor) sollte das Verzeichnis enthalten.

Das erste Diagramm wird mit EXPLAIN.PY erstellt


+1, ließ mich tunalias tee2tty='tee $(readlink /proc/$$/fd/1)'
Tobias Kienzler

7

Versuche dies:

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

6

Hier ist eine Antwort:

Wenn Sie unter X ausgeführt werden, wählen Sie die gewünschte Ausgabe mit der Maus aus, um sie zu kopieren, und klicken Sie dann mit der mittleren Maustaste, um sie einzufügen.

Wenn Sie auf einer Textkonsole arbeiten, können Sie mit gpm Ähnliches tun .


1
+1 - gute Antwort! Mit GNU screen ( gnu.org/software/screen ) können Sie dasselbe erreichen, auch wenn Sie nicht mit X arbeiten .
Simon

1
Es schien so offensichtlich, dass ich zögerte, es zu sagen. Aber alle anderen sind so beschäftigt, klug zu sein. :)
mattdm

es ist die einzige Antwort , hier die der OP ermöglicht die Wiederverwendung der letzten Zeile - alles andere sich bringt wieder den Befehl ausgeführt wird , die zwischen völlig irrelevant und katastrophal könnte überall sein :) Aber das OP Sagten Wiederverwendung .
Simon

@simon: Eigentlich ist meine Antwort nicht. Glenns auch nicht.
Mikel

@Mikel: Stimmt, aber sie erfordern, dass Sie etwas vorher oder beim ersten Mal richtig machen.
Mattdm

1

(Es ist leider keine funktionierende Antwort, aber immer noch etwas Merkwürdiges. Jemand, der interessiert ist, könnte versuchen, die Implementierung der Funktion, über die ich Ihnen erzählen werde, abzuschließen.)

In eshellEmacs wollten sie eine solche Funktion haben, die jedoch nicht vollständig implementiert ist (was sich jedoch in der Dokumentation widerspiegelt ).

Zum Beispiel:

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

~ $ 

Sie sehen, nur die Ausgabe von Builtins kann in der $$Variablen erfasst werden.

Aber gut, etwas Elisp-Programmierung (vgl. eshell-mark-outputImplementierung in "esh-mode.el"), und Sie könnten eine Funktion implementieren, die die letzte Ausgabe "markiert" und sie als Ergebnis der Funktion zurückgibt; Damit Sie diese Funktion in einem von Ihnen angeforderten eshell-Befehl verwenden können, können Sie elisp-Funktionen in eshell-Befehlen mit der üblichen elisp-Syntax verwenden, dh in Klammern wie folgt:

~ $ /bin/echo (buffer-name)
*eshell*
~ $ /bin/echo (car '(a b c))
a
~ $ 

0

Wenn Sie feststellen, dass Sie die Ausgabe vor dem Treffer wiederverwenden möchten Enter, können Sie sie in einer Variablen speichern: Fügen Sie sie tmp=$(am Zeilenanfang und )am Ende hinzu. (Dies entfernt alle Leerzeilen am Ende der Befehlsausgabe und tatsächlich alle letzten Zeilenumbrüche. Dies ist selten von Bedeutung.)

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

Wenn Ihre Shell ksh oder zsh ist, ist dies eine nützliche Funktion, mit der Sie dies automatisieren können. (Dies ist in bash keine Hilfe, da der letzte Befehl in einer Pipeline in der übergeordneten Shell ausgeführt werden muss, was nur in ksh (nicht in pdksh) und zsh der Fall ist.)

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

Verwenden Sie es so:

python -c  |k
cd $kept

0
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" | tee $(readlink /proc/$$/fd/1))

(Aufbauend auf 4485 Antwort )

Das ist viel Tippen, also mach einen Alias:

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

Dann rufen Sie einfach an cd $(python -c ... | tee2tty)

Dies setzt natürlich voraus, dass Sie bereits wissen, was Sie mit der Ausgabe tun möchten, hat aber den Vorteil, dass Sie den Befehl nur einmal aufrufen.



0

Es gibt eine bessere Lösung:

Drucken !!Sie einfach nach dem ausgeführten Befehl und Sie erhalten eine wiederholte Ausgabe.

Z.B

Bildbeschreibung hier eingeben

Original:

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


!!wiederholt nicht das Ergebnis des letzten Befehls, sondern führt den letzten Befehl erneut aus. Wenn jot -r 1 0 1000eine einzelne Zufallszahl zwischen 0 und 1000 zurückgegeben wird 539, gibt running !!höchstwahrscheinlich eine andere Zahl an , nachdem der Befehl einmal ausgeführt und "get" wurde . !!Dies kann auch unerwünscht sein, wenn die Ausführung des vorherigen Befehls viel Zeit in Anspruch nimmt oder wenn ein Vorgang wiederholt wird, der nicht wiederholt werden sollte (z. B. das Ändern einer Datei).
Caleb

1
schöner Fang. Es gibt jedoch einen einfacheren Weg, mich als falsch zu beweisen: echo $ RANDOM; !!
Tebe

Süß - wusste nichts davon! Vielen Dank.
Caleb
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.