จำคำสั่งแบบครึ่งหนึ่งขณะที่ฉันตรวจสอบบางอย่าง


97

ฉันมักจะพบว่าตัวเองอยู่ในตำแหน่งต่อไปนี้: ฉันเริ่มพิมพ์คำสั่งยาวที่พรอมต์ bash แต่ครึ่งทางฉันพบว่าฉันต้องตรวจสอบบางสิ่งด้วยคำสั่งอื่น ปัญหานี้เกิดขึ้นเมื่อฉันอยู่ที่คอนโซล (ไม่ใช่ X) ซึ่งมักเป็นเช่นนี้เพราะฉันมีวิธีที่ไม่น่าพอใจดังต่อไปนี้เท่านั้นที่ฉันรู้:

  • Hit ctrl+ alt+ F2และเข้าสู่ระบบอีกคอนโซลเสมือนจริงและหาสิ่งที่ฉันต้องการจากนั้นกลับไปและดำเนินการต่อ
  • ctrl+ a, พิมพ์ echo + space+ enter, ค้นหาสิ่งที่ฉันต้องการ, กดจนกว่าฉันจะพบคำสั่ง, ctrl+ a, delx 5, ctrl+ e, และทำต่อไป
  • ไฮไลต์สิ่งที่ฉันพิมพ์จนถึงตอนนี้ด้วยเมาส์ของฉัน (ถ้า gpm ทำงานซึ่งปกติแล้ว) กดctrl+ cเพื่อขัดจังหวะค้นหาสิ่งที่ฉันต้องการในขณะที่ระมัดระวังไม่ใช้เมาส์เพื่อไฮไลต์สิ่งต่าง ๆ จากนั้นกดปุ่มกลางของเมาส์ บนพรอมต์ใหม่และดำเนินการต่อ
  • อธิษฐานต่อพระเจ้าบรรทัดคำสั่งว่าคำสั่งแบบครึ่งคำสั่งจะไม่มีผลกระทบใด ๆ แต่ล้มเหลวและกดปุ่มป้อนอย่างละเอียดจากนั้นค้นหาสิ่งที่ฉันต้องการกดให้แคบลงจนกว่าจะได้รับคำสั่งกลับมาและดำเนินการต่อ
  • กระโดดเข้าสู่ไทม์แมชชีนย้อนเวลากลับไปและเตือนตัวเองให้เริ่มหน้าจอก่อนที่จะเริ่มพิมพ์คำสั่งเดินทางกลับสู่ปัจจุบันกดctrl+ a cค้นหาสิ่งที่ฉันต้องการกดctrl+ a ctrl+aและดำเนินการต่อ

ดังนั้นสิ่งที่ฉันอยากรู้คือมีวิธีที่สง่างามกว่านี้บ้างไหม? ประเภทของคำสั่ง subshell หรือคล้ายกัน?

ฉันสนใจวิธีการที่ไม่ต้องการการเตรียมการหรือการตั้งค่าใด ๆ

คำตอบ:


68

รุ่นค่อนข้างเร็วของอเล็กซ์ Ctrl + A Ctrl+ K(ซึ่งจะย้ายไปที่ด้านหน้าของบรรทัดและแล้วก็ตัดทุกอย่างไปข้างหน้า) คือการใช้เพียงCtrl+ Uที่ตัดย้อนหลังในทุบตีและสายทั้งหมด (ไม่คำนึงถึงตำแหน่งปัจจุบันของคุณ) ใน zsh จากนั้นคุณใช้Ctrl+ Yเพื่อวางอีกครั้ง


1
จากการทดสอบนี้ฉันสรุปได้ว่า Ctrl + U ไม่ได้ย้อนกลับและตัดไปข้างหน้า แต่จะตัดไปข้างหลัง การมีเคอร์เซอร์อยู่ตรงกลางของคำสั่งจะทิ้งอะไรก็ตามไว้ข้างหลังบนบรรทัดคำสั่ง ยังคงมีการปรับปรุง 33% สำหรับโซลูชันของ @ alex เนื่องจากช่วยประหยัดการกดแป้นพิมพ์
Lauritz V. Thaulow

2
@lazyr โอ้ใช่แล้ว บนzshมันไม่ตัดสายทั้งหมด แต่เมื่อbashมันตัดไปข้างหลัง ฉันไม่เคยสังเกตเห็นความแตกต่างนั้นมาก่อน
Michael Mrozek

2
โอ้ฉันไม่ทราบว่า Ctrl + U ยังใส่ข้อความเพื่อฆ่าบัฟเฟอร์ ดีที่รู้! :)
อเล็กซ์

1
^U ^Kจะมีผลเช่นเดียวกับแต่เล็กน้อยเหมาะกับการทำงานมากขึ้นและมีความหมายที่สะดวกสบายมากขึ้นภายใต้^A ^K screen
intuited

53

ทำ ctrl-A เพื่อเริ่มต้นบรรทัดเติมแฮชและกด Return - ด้วยวิธีนี้มันจะอยู่ในประวัติคำสั่งเป็นความคิดเห็นและคุณสามารถกลับไปที่เคอร์เซอร์ขึ้นมาได้

แก้ไข: เพิ่งสังเกตเห็นว่านี่เป็นตัวแปรที่หรูหรากว่าใน # 2 ของคุณเล็กน้อย)


1
ใช่แล้วทำไมฉันไม่คิดอย่างนั้นล่ะ ขอขอบคุณ!
Lauritz V. Thaulow

1
ฉันต้องอ่านก่อนโพสต์คำตอบของฉันเอง เจมส์พูดถูก
Sean C.

4
โปรดทราบว่าสิ่งนี้จะไม่ทำงานcshหรือzshเพราะพวกเขาไม่อนุญาตให้แสดงความคิดเห็นในเชลล์เชิงโต้ตอบ ในคุณต้องเปิดใช้งานตัวเลือกที่เหมาะสม:zsh setopt interactive_comments
sam hocevar

1
@Sam ใช่ แต่ ": คำสั่ง" มีผลเหมือนกัน (":" = คำสั่ง null)
barrycarter

6
@barrycarter: ไม่:ควรได้รับการพิจารณาว่าเป็นอันตรายสำหรับวัตถุประสงค์นี้และไม่เคยได้รับการแนะนำ มันจะดำเนินการทุกอย่างหลังจากอัฒภาคภายใน backticks ฯลฯ พร้อมกับผลข้างเคียงที่เกี่ยวข้องทั้งหมด
sam hocevar

29

Hit Ctrl+A, Ctrl+Kเพื่อย้ายไปยังจุดเริ่มต้นของเส้นและลบ (ฆ่า) ไปยังจุดสิ้นสุดของมัน จากนั้นทำวิจัยของคุณและเมื่อพร้อมที่จะกดCtrl+Y(งัด) ต่อไปเพื่อนำบรรทัดที่บันทึกไว้ (ฆ่า) กลับมา


3
อาตอนนี้เป็นเหมือนสิ่งที่ฉันมีอยู่ในใจ และฉันทำเช่นนั้นตลอดเวลาใน Emacs ควรมีความคิดเกี่ยวกับการทำเช่นเดียวกันในบรรทัดคำสั่ง
Lauritz V. Thaulow

13

ใน zsh ฉันพิมพ์Ctrl+ Zเพื่อ“ ระงับ” คำสั่งที่ฉันพิมพ์และพิมพ์คำสั่งอื่น หลังจากที่ฉันเรียกใช้คำสั่งนั้น (หรือยกเลิกด้วยCtrl+ C) คำสั่งที่ถูกระงับจะกลับมาอีกครั้งสำหรับรุ่น (แม้จะจดจำตำแหน่งเคอร์เซอร์) เพื่อความสะดวกเพิ่มเติมหากบรรทัดคำสั่งว่างเปล่าเมื่อฉันพิมพ์Ctrl+ Zคีย์จะเรียกใช้bgบิวด์อินแทน (ดังนั้น double Ctrl+ Zจะส่งคำสั่งที่รันโดยตรงไปยังพื้นหลัง)

fancy-ctrl-z () {
  emulate -LR zsh
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z'          fancy-ctrl-z

ฉันไม่รู้วิธีการทำสิ่งที่คล้ายกันในทุบตี

ในเปลือกใด ๆ ที่คุณสามารถใช้วิธีการเทคโนโลยีต่ำของการเพิ่ม#ที่จุดเริ่มต้นของสายปัจจุบัน


2
ฟังก์ชั่นของคุณน่าชื่นชม แต่คุณรู้หรือไม่ว่าzshมีฟังก์ชั่นสำหรับฟังก์ชั่นที่ติดตั้งมาแล้ว ? มันถูกเรียกpush-lineและสิ่งที่คุณต้องทำคือใช้bindkeyเพื่อไปให้ถึง
แม็กเคเล็บ

@Caleb: ฉันไม่รู้ว่าทำไมฉันถึงใช้push-inputมากกว่าpush-lineที่นี่push-lineดูเหมือนจะเหมาะสมกว่า (อาจเป็น zsh รุ่นเก่าเท่านั้นpush-input) แต่นั่นไม่ใช่สิ่งทดแทนส่วนที่เหลือของฟังก์ชั่น
Gilles

เท่าที่ฉันสามารถบอกได้ว่าความแตกต่างเพียงอย่างเดียวคือเอฟเฟกต์ที่มีผลผูกพันเดียวกันกับพื้นหลังของงานที่กำลังรันอยู่ ฉันพลาดอะไรไปรึเปล่า?
แม็กเคเล็บ

1
@Caleb: ไม่เป็นเพียงฉันพบว่าการรวมกันของทั้งสองสะดวก ( push-lineไม่มีประโยชน์ในบรรทัดว่างการbgเปิดCtrl+Zจะมีประโยชน์ก็ต่อเมื่อฉันเพิ่งระงับกระบวนการด้วยCtrl+Z) และช่วยจำ (ฉันเป็นพื้นหลังทั้งกระบวนการ หรือบรรทัดคำสั่งบางส่วน)
Gilles

3
@Caleb push-inputระงับบัฟเฟอร์อินพุตทั้งหมดในขณะpush-lineที่พักบรรทัดปัจจุบันเท่านั้น หากฉันพิมพ์คำสั่งหลายบรรทัดฉันต้องการระงับคำสั่งทั้งหมดดังนั้นคำสั่งที่push-inputถูกต้อง ผมพบว่าpush-inputมักจะมีประโยชน์มากกว่าpush-line(ถ้าผมต้องการที่จะชะลอบรรทัดในบัฟเฟอร์หลายผมก็สามารถนำทางไปยังจุดเริ่มต้นของเส้นและแทรกขึ้นบรรทัดใหม่) ดังนั้นฉันในความเป็นจริงสงสัยว่าทำไมมีปุ่มลัดเริ่มต้นและไม่push-line push-input
Gilles

13

ในทุบตีเพียงพิมพ์+Alt#

จากนั้นเมื่อคุณพร้อมที่กดUpแล้ว+Alt#

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

จากนั้นเมื่อคุณทำมันอีกเป็นครั้งที่สองมันจะเห็นว่าบรรทัดนั้นมี#การเริ่มต้นแล้วดังนั้นมันจึงจะลบมันและยอมรับมันอีกครั้งช่วยให้คุณประหยัดEnterกุญแจ

หากครั้งที่สองเพิ่งแทรกอีกครั้ง#คุณต้องพิมพ์Alt+ - Alt+ #แทน

คุณสามารถทำให้ zsh ทำเช่นเดียวกันได้โดยใส่

bindkey -M emacs '\e#' pound-insert

ใน ~ / .zshrc ของคุณ

หรือหากคุณใช้การเชื่อม vi คุณสามารถพิมพ์#จากโหมดคำสั่งทั้งใน bash และ zsh


2
ใช้งานไม่ได้สำหรับฉันคำสั่งที่สองหมายถึงการลบ # เพิ่งเพิ่ม # อีก # ของด้านหน้า
Lauritz V. Thaulow

1
คนแรกใช้งานได้หรือไม่? คุณใช้ bash เวอร์ชันใดอยู่
มิเคล

3
Alt + # ทำงานตามที่คุณอธิบายในย่อหน้าที่สามของคุณ แต่ไม่ใช่ในอันดับที่สี่ของคุณเพียงแค่เตรียม # อีกอันไว้ด้านหน้าและยอมรับบรรทัด ฉันใช้ bash 4.1.5 (1) - ปล่อยบน Ubuntu 10.10
Lauritz V. Thaulow

1
โอ้ที่รักในการทุบตีมันต้องมีอาร์กิวเมนต์ที่เป็นตัวเลขเช่นEsc+1จากนั้นAlt+ #เพื่อสลับ
มิเคล

ใช้งานได้ แต่มีความยุ่งยากมากกว่าเพียงแค่ Ctrl + A Del Ctrl + E โดยเฉพาะในรูปแบบแป้นพิมพ์ของฉันโดยที่ Alt + # ในความเป็นจริง Alt + Shift + 3
Lauritz V. Thaulow

10

หนึ่งในคุณสมบัติที่ฉันชอบzshคือฟังก์ชั่น push-line ในตัวที่ดูแลสิ่งนี้โดยไม่มีการแฮ็กในคำตอบอื่น ๆ ที่นี่ ฉันได้ผูกไว้กับCtrl+ lใน.zshrcไฟล์ของฉันเช่นนี้:

bindkey '^L' push-line

จากนั้นเมื่อฉันพิมพ์ตามคำสั่งบางอย่างและต้องทำสิ่งอื่นอย่างรวดเร็วจริงฉันสามารถเรียกใช้งานด้วยปุ่มเดียวและรับการแจ้งเตือนที่ว่างเปล่า หลังจากรันคำสั่งอื่น ๆ พรอมต์จะถูกกรอกโดยอัตโนมัติกับสิ่งที่ฉันพิมพ์มาก่อน

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


5
ผูกพันCtrl+QและESC qโดยค่าเริ่มต้น (ในโหมด emacs)
Gilles

มีบางอย่างที่คล้ายกันสำหรับทุบตี?
แมกนัส

@Magnus: โปรดอ่านคำตอบที่เหลือในคำถามนี้ มีวิธีแก้ปัญหาสำหรับทุบตีไม่หรูหราเท่านี้
Caleb

@Caleb ฉันควรจะเจาะจงมากกว่านี้มีคีย์เดี่ยวแบบเดียวกันสำหรับทุบตีหรือไม่
แมกนัส

1
นี่เป็นคำตอบที่ "ถูกต้อง" อย่างชัดเจนสำหรับ Zsh แล้ว! ฉันแค่อยากจะพูดถึงpush-line-or-editวิดเจ็ตซึ่งไม่ได้อยู่ใน keymap ใด ๆ โดยค่าเริ่มต้น ที่พรอมต์ระดับบนสุดมันทำสิ่งเดียวกันกับpush-lineแต่ที่ระดับพรอมต์ใด ๆ ที่ต่ำกว่าจะแปลงคำสั่งทั้งหมดที่ถูกป้อนไปยังบัฟเฟอร์หลายบรรทัด สองฟังก์ชั่นที่ยอดเยี่ยมในหนึ่งปุ่มลัด! ฉันจะแนะนำให้มีผลผูกพันแทนธรรมดาpush-line-or-edit push-lineคุณจะไม่เสียอะไรเลยและได้รับประโยชน์ใช้สอย
wjv

5

นอกจากนี้ยังมีctrl- a ctrl- kเคล็ดลับถ้าคุณอยู่ในหน้าจอเพียงctrl- a dที่จะแยกออกแล้วใส่กลับเข้าไปด้วยscreen -r

คุณสามารถเปิดอีกหน้าต่างด้วยctrl+a c


8
Ctrl+A cถ้าคุณอยู่ในหน้าจอเพียงแค่เปิดหน้าต่างอีกด้วย
Gilles

1
@Gilles .. เว้นแต่คุณจะต้องใช้บางแง่มุมของสถานะเชลล์ (ตัวแปรฟังก์ชั่นชื่อแทน ฯลฯ )
intuited

4

ทางเลือกที่ไม่สมบูรณ์แบบ Ctrl-X Ctrl-Eแต่กด สิ่งนี้จะเปิดตัวแก้ไขเริ่มต้นของคุณที่มีคำสั่งครึ่งตัว จากนั้นคุณสามารถบันทึกคำสั่งของคุณไปยังไฟล์หรือเปิดเปลือกใหม่จากภายในตัวแก้ไขของคุณ เมื่อคุณออกจากเชลล์ใหม่มันจะกลับสู่เอดิเตอร์และการบันทึกเนื้อหาจะดำเนินการโดยอัตโนมัติ

สิ่งนี้ไม่ได้สมบูรณ์แบบเพราะมันจะไม่ส่งคุณกลับไปที่เชลล์ดั้งเดิมของคุณ แต่อาจบังคับให้ประมวลผลคำสั่งหรือทิ้งมันไป แต่ไม่มีการเลือกชั่วคราวหรือฆ่าบัฟเฟอร์ที่ต้องกังวลและยังมีการปรับแต่งที่ดีเช่นหาก editor = vi

:wq            # execute the command
:cq            # cancel and abort
:! command     # execute command
:shell         # open a new shell
:r filename    # insert the contents of a file for editing
:r ! command   # insert the output of a command for editing

ทางเลือกที่ดีมาก ฉันเป็นคนที่ไม่เชื่อเรื่องพระเจ้าดังนั้นฉันจะมีความสุขที่ได้ใช้หอยเมื่อจำเป็นต้องใช้เครื่องมือไฟฟ้า (เมื่อพูดถึง vi ฉันลองใช้ N64 linux emulator Mupen64Plus เมื่อไม่นานมานี้ Esc ออกจาก emulator โดยไม่บันทึกฉันไม่ยอมแพ้ในไม่ช้าฉันเลิกเล่นทุกอย่าง)
Lauritz V. Thaulow

1
@lazyr สำหรับเดเบียน / อูบุนตูเรียกใช้sudo update-alternatives --config editorแล้วเลือกเครื่องมือแก้ไขที่คุณชื่นชอบ สำหรับระบบอื่น ๆ ให้ตั้งค่าตัวแปรสภาพแวดล้อม EDITOR หรือ VISUAL ให้เป็นตัวแก้ไขรายการโปรดของคุณเช่นเพิ่มexport EDITOR=/usr/bin/nanoใน. bashrc ของคุณ
forcefsck

3

เช่นเดียวกับวิธีการเพิ่ม#ที่จุดเริ่มต้นของบรรทัดมีวิธีที่ง่ายกว่าที่ฉันใช้ซึ่งไม่ต้องการกลับไปที่จุดเริ่มต้นของบรรทัด:

เพียงเพิ่มเครื่องหมายคำพูดเปิดและอย่าปิดมันไม่ว่าจะแบบเดี่ยวหรือสองครั้ง

Enterจากนั้นกดปุ่ม

CtrlCจากนั้นกดปุ่ม

คำสั่งบางส่วนจะถูกบันทึกไว้ในประวัติคำสั่ง (พร้อมใช้งานผ่านลูกศรขึ้น) แต่ไม่ได้ดำเนินการจริง


2

ใช้ zsh ถ้าคุณพิมพ์<ESC> q(escape แล้ว Q) บรรทัดพรอมต์ของคุณจะถูกตัดเพื่อให้คุณสามารถพิมพ์คำสั่งอื่นได้ คุณจะได้รับข้อความที่ตัดกลับอัตโนมัติในพรอมต์ถัดไป

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

ไม่ใช่วิธีที่มีประสิทธิภาพมากที่สุดหากคุณต้องใช้หลายคำสั่งสำหรับการตรวจสอบ / เตรียม (คุณจะต้องพิมพ์อีก<ESC> qครั้งก่อนแต่ละคำสั่ง) แต่ฉันคิดว่ามันเป็นไปได้ที่จะผูกไว้กับทางลัดที่สั้นกว่า


หากคุณต้องการตรวจสอบคู่มือให้พิมพ์<ESC> h(escape แล้วกด H) ที่จะเรียกใช้run-helpบิวด์อินพร้อมกับคำแรกของบรรทัดคำสั่งเป็นอาร์กิวเมนต์ คุณจะพบสายของคุณเหมือนเดิมเมื่อทำเสร็จแล้ว


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