ฉันจะใช้เอาต์พุตล่าสุดจากบรรทัดรับคำสั่งใหม่ได้อย่างไร


44

ฉันต้องการทราบวิธีการใช้ผลลัพธ์สุดท้ายจากคอนโซลเช่น:

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
คุณทำไม่ได้ มีบางคำอธิบายพื้นหลังที่นี่ ทางออกที่ดีที่สุดของคุณคือเรียกใช้คำสั่งอีกครั้งตามที่เห็นในคำตอบสองคำตอบที่โพสต์แล้ว
Gilles 'หยุดความชั่วร้าย'

คุณไม่สามารถจับเอาท์พุทที่ส่งไปยังอุปกรณ์โดยตรงเช่นได้/dev/ttyแต่ควรจับภาพทุกอย่างที่ส่งไปstdoutหรือstderrอาจจะเพียงพอ
มิเคล

@Gilles - เว้นแต่คุณจะใช้คำตอบของ @ mattdm แน่นอน!
simon

@Gilles: แต่อาจมีเชลล์ที่สร้างโดยคนที่จะดักจับ (และส่งผ่าน) เอาต์พุตของคำสั่งและทำให้เอาต์พุตที่ดักจับไว้พร้อมใช้งานสำหรับผู้ใช้เพื่ออ้างถึงจากคำสั่งเพิ่มเติมของเขา บางทีอาจมีบางอย่างที่มีอยู่ไม่ได้เป็นที่นิยมเปลือกหอยที่อนุญาตให้มีภาวะแทรกซ้อนมากหรือน้อย ...
imz - Ivan Zakharyaschev

คำตอบ:


40

สมมติว่าทุบตี:

% 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
ขอบคุณ! ไม่ใช่เรื่องง่ายที่จะพิมพ์ แต่มันจะเกิดขึ้นกับเมาส์
methodofaction

2
คุณสามารถใช้ backticks (ซึ่งฉันไม่สามารถหาวิธีที่จะทำให้ส่วนต่อประสานนี้ไม่ใช่แบบ wikify) แทน $ () แต่ฉันพบว่ามันอึดอัดที่ฉันจะกด backtick-shift-1-shift-1-backtick และฉันพยายามที่จะใช้ $ () เมื่อเป็นไปได้เพื่อประโยชน์ในการอ่าน
jsbillings

@jsbillings ดูคำตอบของฉันด้านล่าง ฉันพิมพ์ \ 'เพื่อแสดง' ในคำตอบ และเพื่อแสดง '\' ตามปกติให้พิมพ์ '\\'
yasouser

3
+1 ฉันสงสัยว่าจะทำรังอย่างไร`backtick-commands`! cd $(dirname $(which python))ที่นี่ฉันมา!
Ed Brannin

21
เพิ่งทราบให้จำไว้ว่านี่เป็นคำสั่งที่รันใหม่ หากคำสั่งของคุณมีผลข้างเคียงนี่อาจไม่เหมาะกับคุณ
Rich Homolka

13

ยังไม่ได้กล่าวถึงให้ใช้ตัวแปร:

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

3
เผง เนื่องจากเป็นเปลือกหอยผู้คนมักจะลืมเกี่ยวกับคุณลักษณะภาษาที่ Bash นำเสนอเช่นลูปและการกำหนด
Evan

สามารถพูดได้cd $dir
ชั่วคราว

3
@Aerovistae ต้องใช้เครื่องหมายอัญประกาศถ้าคุณไม่รู้ว่าค่ามาจากไหน:
glenn jackman

@glenn (ฉันรู้ว่านี่อาจเป็นคำถามอื่นทั้งหมด แต่ถ้าคำตอบสั้น :) คุณช่วยอธิบายเพิ่มเติม / ให้ตัวอย่างที่ไม่ใช้คำพูดจะทำลายสิ่งต่าง ๆ ได้หรือไม่?
alexey

2
คำอธิบายที่ยอมรับได้คือunix.stackexchange.com/questions/171346/…
glenn jackman

8

โซลูชันอื่น ๆ ทั้งหมดเกี่ยวข้องกับการแก้ไขเวิร์กโฟลว์ของคุณหรือเรียกใช้คำสั่งสองครั้งซึ่งอาจไม่เหมาะสมหากใช้เวลานานในการรันหรือไม่สามารถทำซ้ำได้ (เช่นลบไฟล์ - ทำซ้ำมันจะให้ผลลัพธ์ที่ต่างออกไป)

ดังนั้นนี่เป็นแนวคิดที่ซับซ้อนมากขึ้นถ้าคุณต้องการ:

.bashrc

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

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

trap 'rm ~/$$.out' EXIT

ทุบตีให้

$ 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

นี่เป็นปัญหาบางอย่างดังนั้นมันจึงเป็นเพียงจุดเริ่มต้น ตัวอย่างเช่นไฟล์เอาต์พุต ( ~/<pid>.out) อาจมีขนาดใหญ่มากและเติมดิสก์ของคุณ นอกจากนี้เปลือกทั้งหมดของคุณอาจหยุดทำงานหากteeตาย

มันสามารถแก้ไขได้เฉพาะการจับเอาท์พุทจากคำสั่งก่อนหน้าโดยใช้preexecและprecmdhooks ใน zsh หรือการจำลองของพวกเขาในทุบตี แต่ที่ซับซ้อนกว่าที่จะอธิบายที่นี่


6
แนวคิดพื้นฐานนั้นดี แต่การนำไปปฏิบัติไม่เป็นเช่นนั้น เอาต์พุตมาตรฐานในเชลล์เซสชันไม่ใช่เทอร์มินัล แต่เป็นไพพ์ซึ่งจะทำให้บางโปรแกรมทำงานแตกต่างกัน จะไม่มีการซิงโครไนซ์ระหว่างการเขียนไปยัง stdout และการเขียนไปยัง stderr หรือตรงไปยัง tty ดังนั้นตัวอย่างเช่นคุณอาจเห็นเอาต์พุตคำสั่งแสดงขึ้นหลังจากพร้อมต์ถัดไป คุณยังไม่ได้รับการปกป้องteeจากสัญญาณ (ลองกดCtrl+Cแล้วใช้คำสั่งอีกสองสามคำ) ใช้scriptยูทิลิตีที่ไม่มีปัญหาเหล่านี้
Gilles 'หยุดความชั่วร้าย'

ดีแล้วที่รู้! ฉันยังคงทำงานกับพื้นฐานบรรทัดคำสั่งของฉันอยู่ดังนั้นนี่อาจเป็น overkill สำหรับฉันรวมทั้งฉันต้องการที่จะสามารถใช้กับคอมพิวเตอร์เครื่องใดก็ได้ แต่ฉันจะจำได้ถ้าฉันถึงระดับที่ดี
methodofaction

8

ร่างที่ใช้งานได้สำหรับเชลล์แบบดั้งเดิม:

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

ตอนนี้เราสามารถแมวหน้าจอเป็นไฟล์ ต้องการ sudo

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

Apropos screendump: โปรแกรมที่ตั้งชื่อแล้วไม่ได้ผลสำหรับฉันอีกแล้ว อาจเป็นเพราะเมล็ดที่แก่กว่าเท่านั้น / dev / pts / N ก็ไม่ได้ผลสำหรับฉันเช่นกัน บางทีคุณอาจต้องเลือก MKDEV เป็นตัวเลือกใน / dev - ฉันจำได้อย่างมืดมนเกี่ยวกับบางส่วน/dev/cuaNแต่ฉันอาจผิด

เราต้องการที่จะส่งออกท่อแทนที่จะใช้ screen.dump แต่อย่างใดมันไม่ทำงาน - บางครั้งมันก็รอ ENTER

การจับภาพไม่ใช่ไฟล์ข้อความปกติที่มี linefeeds แต่ด้วย - ตัวอย่างเช่น - 80x50 chars ในลำดับเดียว

ในการเลือก 2 บรรทัดสุดท้าย 1 สำหรับเอาต์พุตของคำสั่งและอีกหนึ่งบรรทัดสำหรับบรรทัดที่พร้อมท์ฉันจะเปลี่ยนมันเลือก 160 chars เปลี่ยนกลับอีกครั้งแล้วเลือก 80

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

ในกรณีที่คุณเคยสงสัยว่าทำไมมีrevโปรแกรม

วิจารณ์:

  • คำสั่งแรกจะถูกป้อนดังนั้นการย้ายสาย ahed ดี - แค่การออกกำลังกายเป็นตัวเลขเพื่อเลือกบรรทัดที่ 3 - สุดท้ายหรือบางอย่าง ฉันทำงานเป็นหลักในหน้าต่างอื่น
  • ไม่ใช่ทุกคนที่มีหน้าจอ 80x50 ก็ใช่เรารู้ มี $ COLUMNS และ $ ROWS เพื่อความสุขของคุณ
  • ผลลัพธ์ไม่ได้อยู่ที่ด้านล่าง เปลือกสดและอ่อนอาจอยู่ในแถวบน ง่ายมาก ๆ ประเมินว่าเชลล์ทำงานอะไร ใช้พรอมต์ใด ทำการตรวจหาพร้อมต์บางอย่างและค้นหาบรรทัดสุดท้ายด้วย shell-prompt บรรทัดก่อนหน้า (หรือ 2 ก่อน) ควรมีไดเรกทอรี

ไดอะแกรมแรกนั้นสร้างขึ้นพร้อมกับอธิบายว่า


+1 ทำให้ฉันทำalias tee2tty='tee $(readlink /proc/$$/fd/1)'
โทเบียสคีเอนซ์เลอ

7

ลองสิ่งนี้:

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

6

ดังนั้นเอ่อนี่คือคำตอบ:

หากคุณทำงานภายใต้ X ให้เลือกผลลัพธ์ที่คุณต้องการด้วยเมาส์เพื่อคัดลอกจากนั้นคลิกกลางเพื่อวาง

หากคุณกำลังทำงานอยู่บนคอนโซลข้อความคุณสามารถทำสิ่งที่คล้ายกันกับแกลลอนต่อนาที


1
+1 - คำตอบที่ดี! คุณสามารถบรรลุสิ่งเดียวกันแม้ว่าคุณจะไม่ได้ใช้ X โดยใช้หน้าจอ GNU ( gnu.org/software/screen )
simon

1
ดูเหมือนชัดเจนว่าฉันลังเลที่จะพูด แต่คนอื่น ๆ กำลังยุ่งอยู่กับความฉลาด :)
mattdm

มันเป็นคำตอบเดียวที่นี่ซึ่งจะช่วยให้ OP ที่จะนำมาใช้บรรทัดสุดท้าย - ทุกสิ่งทุกอย่างที่สร้างความเรียกใช้คำสั่งอีกครั้งซึ่งอาจจะเป็นที่ใดก็ได้ระหว่างที่ไม่เกี่ยวข้องอย่างเต็มที่และภัยพิบัติ :) แต่ OP ได้พูดนำมาใช้ใหม่
simon

@simon: ที่จริงแล้วคำตอบของฉันไม่ได้ ไม่เกล็นของ
Mikel

@Mikel: จริง แต่พวกเขาต้องการให้คุณทำอะไรล่วงหน้าหรือถูกต้องในครั้งแรก
mattdm

1

(มันไม่ใช่คำตอบที่ใช้งานได้ แต่น่าเสียดายที่ยังมีบางสิ่งที่อยากรู้อยากเห็นใครบางคนที่สนใจสามารถลองใช้งานคุณลักษณะที่ฉันจะบอกคุณได้)

ในeshellEmacs ภายในพวกเขาต้องการมีคุณสมบัติดังกล่าว แต่ไม่ได้ใช้งานอย่างสมบูรณ์ (ซึ่งสะท้อนให้เห็นในเอกสารประกอบ )

ตัวอย่างเช่น:

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

~ $ 

คุณเห็นเฉพาะการส่งออกของ builtins เท่านั้นที่สามารถบันทึกลงใน$$ตัวแปรได้

แต่การเขียนโปรแกรม elisp บางตัว ( eshell-mark-outputการใช้งานใน "esh-mode.el") และคุณสามารถใช้ฟังก์ชั่นที่ "ทำเครื่องหมาย" เอาท์พุทสุดท้ายและส่งกลับเป็นผลของฟังก์ชั่น; เพื่อให้คุณสามารถใช้ฟังก์ชันนั้นในคำสั่ง eshell ที่คุณต้องการ - ฟังก์ชัน elisp สามารถใช้ในคำสั่ง eshell ด้วยไวยากรณ์ elisp ปกติเช่นในวงเล็บดังนี้:

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

0

หากคุณรู้ว่าคุณจะต้องการนำเอาท์พุทกลับมาใช้ใหม่ก่อนที่คุณจะตีEnterคุณสามารถบันทึกลงในตัวแปร: เพิ่มtmp=$(ที่จุดเริ่มต้นของบรรทัดและ)ท้าย (สิ่งนี้จะลบบรรทัดว่างใด ๆ ที่ส่วนท้ายของเอาต์พุตคำสั่งและในความเป็นจริงจะลบบรรทัดใหม่สุดท้ายใด ๆ ซึ่งไม่ค่อยเกิดขึ้น)

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

หากเชลล์ของคุณคือ ksh หรือ zsh นี่คือฟังก์ชั่นที่มีประโยชน์ที่คุณสามารถใช้เพื่อทำให้เป็นอัตโนมัติมากขึ้น (ไม่มีความช่วยเหลือในการทุบตีเพราะต้องการคำสั่งสุดท้ายในไพพ์ไลน์ที่จะดำเนินการใน parent parent ซึ่งเป็นกรณีเฉพาะใน ksh (ไม่ใช่ pdksh) และ zsh)

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

ใช้วิธีนี้:

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 )

นั่นคือการพิมพ์จำนวนมากดังนั้นให้นามแฝง:

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

จากนั้นก็โทร cd $(python -c ... | tee2tty)

หลักสูตรนี้กำหนดให้คุณต้องทราบว่าคุณต้องการทำอะไรกับเอาต์พุต แต่มีข้อดีของการเรียกคำสั่งเพียงครั้งเดียว


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

จะทำเคล็ดลับ

อ่านที่นี่เพื่อดูรายละเอียดเพิ่มเติมได้ที่: แทนคำสั่ง


1
arumug: บาฮามาตได้โพสต์คำตอบเดียวกันเกือบหมดแล้ว เวอร์ชันของคุณที่มี backticks จะไม่ทำงานหากมี backticks ในคำสั่งอยู่แล้ว
Gilles 'ดังนั้นหยุดความชั่วร้าย'

0

มีทางออกที่ดีกว่าคือ

เพียงพิมพ์!!คำสั่งที่ดำเนินการแล้วคุณจะได้รับผลลัพธ์ซ้ำ

เช่น

ป้อนคำอธิบายรูปภาพที่นี่

เดิม:

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


!!ไม่ซ้ำผลลัพธ์จากคำสั่งสุดท้ายมันจะรันคำสั่งสุดท้ายอีกครั้ง หากjot -r 1 0 1000ส่งกลับตัวเลขสุ่มเดียวระหว่าง 0 ถึง 1,000 จากนั้นหลังจากเรียกใช้คำสั่งนั้นครั้งเดียวและได้รับ539แล้วการรัน!!มักจะให้หมายเลขอื่น ๆ !!อาจไม่เป็นที่พึงปรารถนาหากคำสั่งก่อนหน้าใช้เวลาในการรันนานหรือดำเนินการซ้ำที่ไม่ควรทำซ้ำ (เช่นการเปลี่ยนไฟล์)
แม็กเคเล็บ

1
รับได้สวย. แม้ว่าจะมีวิธีที่ง่ายกว่าที่จะพิสูจน์ว่าฉันผิด: echo $ RANDOM; !!
Tebe

น่ารัก - ไม่รู้เรื่องเลย! ขอบคุณ
แม็กเคเล็บ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.