วิธีรันคำสั่งติดต่อกันจากประวัติ


49

สมมติว่าฉันต้องการรันคำสั่งสี่คำสั่งที่ฉันได้ดำเนินการมาก่อน หากคนแรกคือ 432 ในประวัติศาสตร์คำสั่งจากนั้นฉันสามารถทำได้:

$ !432; !433; !434; !435

ฉันอยากรู้อยากเห็นมีวิธีที่มีประสิทธิภาพมากขึ้นเพื่อให้บรรลุนี้


1
ไม่โพสต์สิ่งนี้เป็นคำตอบเพราะไม่ได้ใช้คำสั่ง แต่คุณสามารถhistory -p \!43{2..5}พิมพ์คำสั่ง 432 ถึง 435 ไปยังเทอร์มินัลได้ซึ่งเหมาะสำหรับการคัดลอก / วางในภายหลัง
Wildcard

คำตอบ:


48

ถ้ามันหมายถึงคำสั่งที่เพิ่งรันเมื่อเร็ว ๆ นี้วิธีที่มีประสิทธิภาพมากขึ้นคือการอ้างอิงมันด้วยจำนวนลบ

!-4; !-3; !-2; !-1

!!นอกจากนี้เมื่อคุณทำมันรายการประวัติศาสตร์ที่ผ่านมาของคุณจะมีห่วงโซ่ทั้งหมดของคำสั่งเพื่อให้คุณสามารถทำซ้ำได้ด้วย


แก้ไข: หากคุณยังไม่ได้ทำความคุ้นเคยกับฟังก์ชั่นในตัวที่ดีfc,กล่าวโดยกิลส์ (ใช้help fc) ปรากฎว่าคุณสามารถใช้ตัวเลขติดลบได้ดังนั้นคุณสามารถทำเช่นเดียวกับการใช้ข้างต้น

eval "`fc -ln -4 -1`"

สิ่งนี้มีหนึ่งข้อแม้แม้ว่า: หลังจากนี้evalบรรทัดจะถูกเก็บไว้ในประวัติเป็นคำสั่งสุดท้าย ดังนั้นหากคุณเรียกใช้อีกครั้งคุณจะตกหลุม!

วิธีที่ปลอดภัยกว่าในการทำเช่นนี้คือการใช้fcโหมดการทำงานเริ่มต้น: ส่งต่อคำสั่งที่เลือกไปยังตัวแก้ไขและเรียกใช้เมื่อคุณออกจากมัน ลอง:

 fc -4 -1

คุณสามารถย้อนกลับลำดับของช่วงของคำสั่ง: fc -1 -4


ฉันเพิ่งอ่านสิ่งที่ฉันเขียน ... ฮ่า ๆ ที่จริงแล้วฉันไม่แน่ใจเกี่ยวกับreinvoke ( อาจเรียกอีกครั้ง ?) แต่ขอบคุณที่บอก :) ฉันมักจะชื่นชมการแก้ไข
rozcietrzewiacz

Scrabblefinder.com พูดว่า reinvoke เป็นคำ Scrabble ที่ถูกต้อง ไม่สามารถรับได้มากกว่าที่แน่นอน :)
BentFX

1
ด้วยคำตอบที่ดีเช่นนี้ (+1) มันไม่สำคัญว่าคุณจะสะกดอย่างไร โดยเฉพาะอย่างยิ่งเมื่อไม่มีรูปแบบการสะกดคำปรากฏขึ้นในพจนานุกรมภาษาอังกฤษที่สำคัญ 3 ฉบับ: Oxford, Camgridge, Merriam-Webster (ฉันจะไปหายัติภังค์)
Peter.O

34

ในการดูคำสั่งต่าง ๆ ในประวัติศาสตร์ให้ใช้fcคำสั่งในตัว:

fc -ln 432 435

หากต้องการดำเนินการอีกครั้ง:

eval "$(fc -ln 432 435)"

4
ดีมาก. ฉันอยากรู้ว่าทำไมman fcไม่ให้อะไรฉัน สิ่งที่fcยืนหยัดเพื่อ? มีตัวเลือกอื่น ๆ อีกบ้าง?
Eric Wilson

2
@Eric Wilson ... พิมพ์help fc... และยังhelp help.... ช่วยด้วย: help [-dms] [pattern ... ] แสดงข้อมูลเกี่ยวกับคำสั่ง builtin
Peter.O

ฉันเพิ่งกลับมาที่นี่ค้นหาคำตอบของคุณ นี่เป็นสิ่งที่ยอดเยี่ยมในตัว! โดยเฉพาะอย่างยิ่งเมื่อคุณเป็นฟังก์ชันเริ่มต้น - เรียกใช้ตัวแก้ไขเพื่อปรับเปลี่ยนช่วงของคำสั่งที่จะเล่นซ้ำ ขอบคุณ Gilles
rozcietrzewiacz

1
โดยไม่ต้องธงก็จะดำเนินการโดยไม่ต้องใช้ความชั่วร้าย-l eval
แบร์นฮาร์ด

1
@EricWilson google ค้นหานำฉันไป "ยูนิกซ์ในกะลา" หนังสือที่บอกว่าfcย่อมาจาก "พบคำสั่ง" หรือ "แก้ไขคำสั่ง"
Slothworks

10

มีวิธีที่ดีและเป็นทางเลือกในการรันคำสั่งจำนวนมากตามลำดับจากประวัติ Bash:
แทนที่จะใช้การแทนที่ประวัติ ( !432หรือ!-4) คุณสามารถค้นหาประวัติด้วยCtrl+ rและเมื่อคุณพบคำสั่งแรกที่คุณต้องการ เรียกใช้, กดCtrl+ o( ใช้งานและรับถัดไป ) แทนreturnปุ่ม
ซึ่งจะเปิดใช้คำสั่งและเสนอคำสั่งถัดไปจากประวัติ คุณสามารถเข้าชมได้Ctrl+oหลายครั้งตามที่คุณต้องการและจบลำดับด้วยreturnตัวสุดท้ายหรือCtrl+cหยุดโดยไม่เปิดตัว


อืมหลังจากที่ผมตีCtrl-oมันก็ outputs ตัวอักษรและแบ่งของฉัน^o (reverse-i-search)อาจมีการตั้งค่าอื่น ๆ ที่เกี่ยวข้อง
Ciro Santilli 新疆改造中心法轮功六四事件

8

หากต้องการดำเนินการคำสั่งทันทีแทนที่จะแก้ไขคำสั่งนี่คือคำตอบแบบไจล์ของซิลลีที่มีขนาดเล็กลงโดยใช้ eval :

fc -e: 432 435

อาร์กิวเมนต์โคลอนของ -e คือ bash noop ซึ่งมีผลในการข้ามขั้นตอน "open in a editor" ที่ fc ต้องการ นอกจากนี้ตอนนี้ประวัติ (ล่าสุด) จะมีคำสั่งจริงจากประวัติมากกว่าคำสั่ง eval


0

fc สำหรับห่วงและ xsel

สิ่งนี้ใช้ได้ดีเมื่อฉันต้องการเชื่อมและรันคำสั่ง n ล่าสุดซ้ำหลาย ๆ ครั้ง:

fcn() (
  from="${1:-2}"
  to="${2:-1}"
  if [ "$from" -ne "$to" ]; then
    for i in `seq "$from" -1 "$(($to + 1))"`; do
      printf "$(fc -ln -${i} -${i}) && "
    done
  fi
  printf "$(fc -ln -${to} -${to})"
)

แล้ว:

$ echo a
a
$ echo b
b
$ echo c
c
$ fcn 3 1 | xsel -b
$ # Paste.
$  echo a &&  echo b &&  echo c
a
b
c
$ # Paste again if you feel like it.
$  echo a &&  echo b &&  echo c
a
b
c

หรือสำหรับคำสั่งขนาดใหญ่ที่อาจต้องมีการแก้ไข:

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