Komut satırından son çıktıyı nasıl yeniden kullanırım?


44

Konsoldan son çıktının nasıl tekrar kullanılacağını bilmek istiyorum, yani:

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
Yapamazsın; Burada bazı arka plan açıklaması var . En iyi bahis, şu ana kadar verilen iki cevapta görüldüğü gibi, komutu tekrar çalıştırmaktır.
Gilles 'SO- kötülük' dur

Doğrudan gibi bir aygıta gönderilen çıktıyı yakalayamazsınız /dev/tty, ancak bu, stdoutya stderrda yeterli olabilecek bir şeyi yakalamanız mümkün olmalıdır .
Mikel

@Gilles - Tabii ki @ mattdm'in cevabını kullanmazsan!
Simon

@Gilles: ancak biri tarafından yaratılan, komutların çıktılarını yakalayacak (ve geçecek) ve yakalanan çıktıları kullanıcının ileri komutlarından referans alabilmesi için uygun hale getirecek bir kabuk olabilir. Belki, daha fazla veya daha az komplikasyonla buna izin veren çok popüler olmayan bazı mermiler bile var ...
imz - Ivan Zakharyaschev 16.01

Yanıtlar:


40

Bash varsayarak:

% 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
Teşekkürler! Yazması çok kolay değil, ancak fareyi kullanmadan atıyor.
metodofaction

2
Ayrıca $ () yerine backtick'leri (bu arabirimin nasıl wikify yapmamasını sağlayamadığımı çözebilirsiniz) yerine $ () kullanabilirsiniz. ve okunabilirlik uğruna mümkün olduğunda $ () kullanma alışkanlığı kazanmaya çalışıyorum.
jsbillings

@ jsbillings yanıtımı aşağıda görüyor. Cevapta \ `görüntülemek için` yazdım. Ve her zaman olduğu gibi '\' gösterilsin.
yasouser

3
+1 Nasıl yuva yapılacağını merak ediyorum `backtick-commands`! cd $(dirname $(which python))işte geliyorum!
Ed Brannin

21
Sadece bir not, bunun komutu zorlaştırdığını hatırla. Komutunuzun yan etkileri varsa, bu sizin için işe yaramayabilir.
Rich Homolka

13

Henüz belirtilmemiş, bir değişken kullanın:

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

3
Kesinlikle. Bir kabuk olduğu için, insanlar genellikle döngü ve atama gibi Bash'in sunduğu dil özelliklerini unuturlar.
Evan

sadece söyleyebilirimcd $dir
temporary_user_name

3
@ Aerovistae, değerin nereden geldiğini bilmiyorsanız, tırnak işaretleri gereklidir:
glenn jackman

@glenn, (Bunun tamamen başka bir soru olabileceğini biliyorum, ama cevap kısaysa :) daha fazla açıklar mısın / tırnak kullanmamanın bazı şeyleri bozabileceği bir örnek verebilir misin?
alexey


8

Diğer tüm çözümler, iş akışınızı değiştirmeyi veya komutu iki kez çalıştırmayı içerir; bu, çalışması uzun zaman alıyorsa veya tekrar edilemiyorsa uygun olmayabilir (örn. Farklı bir sonuç üreteceğini gösteren bir dosyayı siler).

İhtiyacınız olursa işte daha karmaşık bir fikir:

Bashrc

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

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

trap 'rm ~/$$.out' EXIT

bash istemi

$ 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

Bunun bazı sorunları var, bu yüzden sadece bir başlangıç ​​noktası olarak ifade edildi. Örneğin, çıktı dosyası ( ~/<pid>.out) çok büyüyebilir ve diskinizi doldurur. Ayrıca, tüm kabuğunuz teeölürse çalışmayı durdurabilir .

Sadece kullanarak önceki komutunun çıktısını yakalamak için modifiye edilebilir preexecve precmdkancaları zsh içinde veya bunların bir öykünme bash, ama bu daha burada açıklamak için karmaşıktır.


6
Temel fikir iyidir, ancak uygulama değildir. Kabuk oturumundaki standart çıktı bir terminal değil, bazı programların farklı davranmasına neden olacak bir borudur. Yazma ile stdout ve yazma ile stderr arasında doğrudan bir senkronizasyon olmayacaktır, bu nedenle örneğin bir sonraki komut isteminden sonra görüntülenen komut çıkışını görebilirsiniz. Ayrıca teesinyallerden korunmadınız (basıp Ctrl+Cdaha çok sayıda komut çalıştırmayı deneyin ). scriptBu sorunların hiçbiri bulunmayan yardımcı programı kullanın .
Gilles 'SO- kötülük'

Bilmek güzel! Komut satırıyla ilgili temel bilgilerim üzerinde çalışıyorum, bu yüzden bu muhtemelen benim için çok büyük bir engel, artı herhangi bir bilgisayarda kullanabilmek istiyorum, ancak iyi bir seviyeye ulaşırsam hatırlayacağım.
metodofaction

8

Geleneksel bir kabuk için çalışan bir taslak:

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

Şimdi ekranı bir dosyaya çevirebiliriz. Sudo gerekiyor.

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

Apropos screendump: Yani adlandırılmış program artık benim için çalışmıyor. Belki sadece daha yaşlı çekirdekler için. / dev / pts / N de benim için işe yaramadı. Belki de / dev içindeki bazı isteğe bağlı MKDEV'lere mecbursunuz - bazılarını karanlık olarak hatırlıyorum /dev/cuaN, ancak hatalı olabilirim.

Screen.dump kullanmak yerine çıktıyı borulamak istiyoruz. Ama bir şekilde işe yaramıyor - bazen ENTER için bekler.

Yakalama, satır beslemeli normal bir metin dosyası değil, - örneğin - bir sırayla - 80x50 karakter ile.

Son 2 satırı, komutun çıktısı için 1, komut satırı için bir tane seçmek için, onu geri döndürürüm, 160 karakter seçer, tekrar döndürür ve 80'i seçerim.

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

Merak ettin de, neden bir revprogram var?

Eleştiri:

  • İlk komutlar girilir, böylece çizgi ahed hareket ettirilir. Şey - sadece sonuncu çizgiyi seçmek için yapılan sayısal bir alıştırma. Genelde farklı bir pencerede çalıştım.
  • Herkes 80x50 ekrana sahip değildir. Evet, biliyoruz. Zevkiniz için $ COLUMNS ve $ ROWS var.
  • Çıktı daima altta değil. Taze ve genç bir kabuk üst sıralarda olabilir. Peki - bu kadar basit: Hangi kabuğun çalıştığını değerlendirin. Hangi istemi kullanılır. İstemi algılamayı yapın ve bir kabaca istemi olan son satırı bulun. Önündeki satır (veya önceki 2.) dizini içermelidir.

İlk diyagram açıkla.py ile yapıldı.


+1, beni yaptıalias tee2tty='tee $(readlink /proc/$$/fd/1)'
Tobias Kienzler 18:11

7

Bunu dene:

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

6

Yani, işte bir cevap:

X altında çalışıyorsanız, kopyalamak için fareyle istediğiniz çıkışı seçin ve ardından yapıştırmak için orta tıklayın.

Bir metin konsolunda çalışıyorsanız, gpm ile benzer bir şey yapabilirsiniz .


1
+1 - iyi cevap! GNU ekranını ( gnu.org/software/screen ) kullanarak, X çalıştırmasanız bile aynı şeyi başarabilirsiniz .
Simon

1
O kadar açık gibiydi ki söylemekte tereddüt ettim. Ama diğer herkes zeki olmakla meşgul. :)
mattdm 11:11

OP'nin son çizgiyi tekrar kullanmasına izin veren tek cevap budur - diğer her şey komutun tekrar çalıştırılmasını gerektirir, bu da tamamen alakasız ve felaket arasında bir yerde olabilir :) Fakat OP yeniden kullanma demiş .
Simon

@ simon: Aslında cevabım değil. Glen de öyle değil.
Mikel

@Mikel: Doğru, ama önceden veya doğru bir şekilde ilk defa bir şey yapmanı istiyorlar.
mattdm

1

(Maalesef çalışan bir cevap değil, ama yine de meraklı bir şey. İlgilenen biri size anlatacağım özelliğin uygulanmasını tamamlamaya çalışabilir.)

In eshellEmacs içinde, böyle bir özelliği var istedim ama (ancak bir tam şekilde uygulanan değil belgelerinde yansıyan ).

Örneğin:

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

~ $ 

Görüyorsunuz, $$değişkenlerin yalnızca çıktıları yakalanabilir .

Ancak, bazı elisp programlama (bkz eshell-mark-output. "Esh-mode.el" deki uygulama) ve son çıktıyı "işaretleyen" ve onu fonksiyonun sonucu olarak döndüren bir fonksiyon uygulayabilirsiniz; böylece bu işlevi istediğiniz bir eshell komutunda kullanabilirsiniz - elisp işlevleri, normal elisp sözdizimi ile eshell komutlarında, örneğin parantez içinde, örneğin:

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

0

Çıktıyı çarpmadan önce tekrar kullanmak isteyeceğinizi fark ederseniz Enter, bir değişkene kaydedebilirsiniz: tmp=$(satırın başına ve )sonuna ekleyin . (Bu, komut çıktısının sonundaki boş satırları kaldırır ve aslında son satırların tümünü kaldırır; bu nadiren önemlidir.)

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

Eğer kabuğunuz ksh veya zsh ise, işte bunu daha otomatik hale getirmek için kullanabileceğiniz kullanışlı bir fonksiyon. (Bash'ta yardımcı değildir, çünkü bir boru hattındaki son komutu ana kabukta çalıştırılması gerekir, bu sadece ksh (pdksh değil) ve zsh'dır.)

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

Bu şekilde kullanın:

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

( 4485'in cevabını oluşturmak )

Çok fazla yazarak, takma ad verin:

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

O zaman basitçe ara cd $(python -c ... | tee2tty)

Bu, elbette çıktı ile ne yapmak istediğinizi bilmenizi gerektirir, ancak komutu yalnızca bir kez çağırma avantajına sahiptir.



0

Daha iyi bir çözüm var:

Sadece !!exec komutundan sonra yazdırın ve tekrarlanan çıktı alacaksınız.

Örneğin

görüntü tanımını buraya girin

Orijinal:

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


!!Son komutun sonucunu tekrarlamaz, son komutu tekrar çalıştırır. Eğer jot -r 1 0 1000getiriler 0 ile 1000 arasında bir tek rasgele sayı, daha sonra bir kez bu komutu çalıştırıp aldıktan sonra 539, koşu !!büyük olasılıkla başka numara verecektir. !!önceki komutun çalışması çok uzun sürerse veya tekrarlanmaması gereken bir işlemi tekrarlarsa (bir dosyayı değiştirmek gibi) istenmeyen bir durum olabilir.
Caleb

1
güzel yakalayış. Yanlış olduğumu kanıtlamanın daha kolay bir yolu olsa da: echo $ RANDOM; !!
Tebe

Tatlı - bunu bilmiyordum! Teşekkürler.
Caleb
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.