Ingat perintah setengah mengetik saat aku memeriksa sesuatu

97

Saya sering menemukan diri saya dalam posisi berikut: Saya sudah mulai mengetik perintah panjang di bash prompt, tetapi setengah jalan saya menemukan saya perlu memeriksa sesuatu dengan perintah lain. Ini adalah masalah ketika saya berada di konsol (tidak ada X), yang sering terjadi, karena saya hanya memiliki cara tidak memuaskan berikut untuk melakukannya, yang saya tahu:

  • Tekan ctrl+ alt+ F2dan masuklah ke konsol virtual lain, dan cari tahu apa yang saya inginkan, lalu kembali dan lanjutkan
  • ctrl+ a, ketik echo + space+ enter, cari tahu apa yang saya inginkan, tekan hingga saya menemukan perintah saya, ctrl+ a, delx 5, ctrl+ e, dan lanjutkan
  • Sorot apa yang telah saya ketik sejauh ini dengan mouse saya (jika gpm sedang berjalan, seperti biasanya), tekan ctrl+ cuntuk menyela, cari tahu apa yang saya inginkan sambil berhati-hati untuk tidak menggunakan mouse saya untuk menyorot hal-hal, lalu tekan tombol tengah mouse pada prompt baru dan lanjutkan
  • Berdoa kepada dewa-dewa command line bahwa perintah setengah-tertulis tidak akan memiliki efek buruk tetapi gagal, dan tekan enter dengan hati-hati, kemudian cari tahu apa yang saya inginkan, tekan uparrow sampai saya mendapatkan kembali perintah saya, dan lanjutkan
  • Lompat ke mesin waktu saya, kembali ke masa lalu dan ingatkan diri saya untuk memulai layar sebelum mulai mengetik perintah, bepergian kembali ke masa sekarang, tekan ctrl+ a c, cari tahu apa yang saya inginkan, tekan ctrl+ a ctrl+a, dan lanjutkan

Jadi yang ingin saya ketahui adalah, adakah cara yang lebih elegan untuk melakukan ini? Semacam perintah subshell atau serupa?

Saya paling tertarik dengan metode yang tidak memerlukan persiapan atau pengaturan apa pun untuk berfungsi.

Lauritz V. Thaulow
sumber

Jawaban:

68

Versi alex's Ctrl + A Ctrl+ Kyang agak lebih cepat (yang bergerak ke depan baris dan kemudian memotong segalanya ke depan) adalah dengan menggunakan Ctrl+ U, yang memotong mundur pada bash, dan seluruh baris (terlepas dari posisi Anda saat ini) di zsh. Kemudian Anda menggunakan Ctrl+ Yuntuk menempelkannya lagi

Michael Mrozek
sumber
1
Menguji ini, saya menyimpulkan bahwa Ctrl + U tidak bergerak mundur dan memotong maju, melainkan memotong mundur. Memiliki kursor di tengah perintah meninggalkan apa pun yang ada di belakangnya di baris perintah. Namun, masih ada peningkatan 33% dari solusi @ alex, karena menghemat penekanan tombol.
Lauritz V. Thaulow
2
@ Lazyr Oh, benar sekali; di zshatasnya memotong seluruh baris, tetapi di bashatasnya memotong mundur. Saya tidak pernah memperhatikan perbedaan itu sebelumnya
Michael Mrozek
2
Oh, saya tidak tahu Ctrl + U juga meletakkan teks untuk membunuh buffer. Bagus untuk mengetahui! :)
alex
1
^U ^Kakan memiliki efek yang sama ^A ^Ktetapi sedikit lebih ergonomis, dan secara signifikan lebih nyaman screen.
intuited
53

Lakukan ctrl-A untuk memulai baris, tambahkan hash dan tekan kembali - dengan cara ini akan tetap dalam sejarah perintah sebagai komentar dan Anda dapat kembali ke sana dengan kursor naik

EDIT: cukup perhatikan ini adalah varian yang sedikit lebih elegan di # 2;)

jamespo
sumber
1
Ya, dan mengapa saya tidak memikirkan itu? Terima kasih!
Lauritz V. Thaulow
1
Saya perlu membaca sebelum memposting jawaban saya sendiri. James benar.
Sean C.
4
Perhatikan bahwa ini tidak akan berfungsi cshatau zshkarena mereka tidak mengizinkan komentar di shell interaktif. Dalam zshAnda perlu mengaktifkan pilihan yang tepat: setopt interactive_comments.
sam hocevar
1
@ Sam Ya, tapi ": command" memiliki efek yang sama (":" = the null command)
barrycarter
6
@barrycarter: tidak, :harus dianggap berbahaya untuk tujuan ini dan tidak pernah disarankan. Ini akan menjalankan semuanya setelah tanda titik koma, di dalam backticks dll dengan semua efek samping yang terkait.
sam hocevar
29

Tekan Ctrl+A, Ctrl+Kuntuk pindah ke awal baris dan menghapus (bunuh) sampai akhir. Kemudian lakukan riset Anda, dan ketika siap untuk melanjutkan tekan Ctrl+Y(menarik) untuk mengembalikan garis Anda yang sudah disimpan (terbunuh).

alex
sumber
3
Ah, sekarang ini lebih seperti apa yang ada dalam pikiran saya. Dan saya melakukan itu sepanjang waktu di Emacs, seharusnya berpikir untuk melakukan hal yang sama pada baris perintah.
Lauritz V. Thaulow
13

Di zsh, saya mengetik Ctrl+ Zuntuk "menangguhkan" perintah yang saya ketikkan dan ketik perintah lain. Setelah saya menjalankan perintah itu (atau membatalkannya dengan Ctrl+ C), perintah yang ditangguhkan kembali untuk edisi (bahkan mengingat posisi kursor). Sebagai kenyamanan tambahan, jika baris perintah kosong ketika saya mengetik Ctrl+ Z, kunci akan memanggil bgbuilt-in sebagai gantinya (jadi dua kali lipat Ctrl+ Zmengirimkan perintah yang berjalan langsung ke latar belakang).

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

Saya tidak tahu bagaimana melakukan sesuatu yang mirip di bash.

Dalam shell apa pun, Anda dapat menggunakan metode menambahkan# teknologi rendah di awal baris saat ini .

Gilles
sumber
2
fungsi Anda mengagumkan, tetapi apakah Anda tahu bahwa zshmemiliki fungsi untuk itu dibangun di sudah ? Ini dipanggil push-linedan yang perlu Anda lakukan hanyalah menggunakannya bindkeyuntuk mendapatkannya.
Caleb
@ Caleb: Saya tidak tahu mengapa saya menggunakan push-inputdaripada di push-linesini, push-lineapakah sepertinya lebih tepat (mungkin versi lama dari zsh hanya punya push-input?). Tapi itu bukan pengganti untuk sisa fungsi.
Gilles
Sejauh yang saya tahu satu-satunya perbedaan adalah efek mengikat yang sama dengan latar belakang pekerjaan yang sedang berjalan. Apakah saya melewatkan sesuatu?
Caleb
1
@ Caleb: Tidak, hanya saja saya menemukan kombinasi keduanya nyaman ( push-linetidak berguna pada baris kosong, setelah bgpada Ctrl+Zhanya berguna ketika saya baru saja menunda proses itu dengan Ctrl+Z) dan mnemonic (Saya baik latar belakang proses atau baris perintah parsial).
Gilles
3
@ Caleb push-inputmenangguhkan seluruh buffer input, sedangkan push-linehanya menangguhkan baris saat ini. Jika saya mengetik perintah multiline, saya ingin menunda seluruh perintah, begitu push-inputjuga yang benar. Saya menemukan push-inputlebih sering berguna daripada push-line(jika saya ingin menunda baris dalam buffer input multiline, saya hanya dapat menavigasi ke awal baris dan memasukkan baris baru), jadi saya sebenarnya bertanya-tanya mengapa push-linemendapat keybinding default dan tidak push-input.
Gilles
13

Di bash, cukup ketik Alt+ #.

Kemudian ketika Anda siap, tekan Uplalu Alt+ #.

Yang pertama menempatkan a #di awal baris untuk mengubahnya menjadi komentar, kemudian menerima baris, seolah-olah Anda telah menekan Enter.

Kemudian, ketika Anda melakukannya untuk kedua kalinya, ia melihat garis sudah memiliki #di awal, sehingga menghapusnya, dan menerimanya, lagi menyelamatkan Anda Enterkunci.

Jika kedua kalinya hanya memasukkan yang lain #, maka Anda harus mengetik Alt+ - Alt+ #sebagai gantinya.

Anda dapat membuat zsh melakukan hal yang sama dengan meletakkan

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

di ~ / .zshrc Anda.

Atau, jika Anda menggunakan vi bindings, Anda dapat mengetik #dari mode perintah di bash dan zsh.

Mikel
sumber
2
Tidak berfungsi untuk saya, perintah kedua dimaksudkan untuk menghapus # hanya menambahkan lebih banyak # di depan.
Lauritz V. Thaulow
1
Apakah yang pertama berhasil? Versi bash apa yang Anda gunakan?
Mikel
3
Alt + # berfungsi seperti yang Anda gambarkan dalam paragraf ketiga Anda, tetapi tidak seperti pada paragraf keempat Anda, # # hanya akan menambah # depan ke depan dan menerima baris. Saya menggunakan bash 4.1.5 (1) -release di Ubuntu 10.10.
Lauritz V. Thaulow
1
Oh dear, di bash membutuhkan argumen numerik, misalnya Esc+1kemudian Alt+ #untuk beralih.
Mikel
Itu bekerja, tetapi jauh lebih rumit dari hanya Ctrl + A Del Ctrl + E, terutama pada tata letak keyboard saya di mana Alt + # sebenarnya Alt + Shift + 3.
Lauritz V. Thaulow
10

Salah satu fitur favorit saya zshadalah fungsi push-line bawaan yang menangani ini tanpa ada peretasan di jawaban lain di sini. Saya sudah terikat ke Ctrl+ ldi .zshrcfile saya seperti ini:

bindkey '^L' push-line

Kemudian ketika saya mengetikkan beberapa perintah dan perlu melakukan sesuatu yang lain dengan sangat cepat, saya dapat memohonnya dengan satu kunci dan mendapatkan prompt kosong. Setelah menjalankan perintah lain, prompt secara otomatis diisi dengan apa yang saya ketikkan sebelumnya.

Anda bahkan dapat rantai beberapa lapisan ini dan perintah akan kembali kepada Anda dalam urutan terbalik sehingga Anda mendorong mereka ke dalam antrian.

Caleb
sumber
5
Terikat ke Ctrl+Qdan ESC qsecara default (dalam mode emacs).
Gilles
Apakah ada yang mirip dengan bash?
Magnus
@Magnus: Silakan tinjau sisa jawaban pada pertanyaan ini. Ada solusi untuk bash, hanya saja tidak seanggun ini.
Caleb
@ Caleb, saya seharusnya lebih spesifik, apakah ada kombinasi tombol tunggal yang sama untuk bash?
Magnus
1
Ini jelas jawaban yang "benar", untuk Zsh toh! Saya hanya ingin menyebutkan push-line-or-editwidget, yang tidak terikat keymap apa pun secara default. Pada prompt tingkat atas, ia melakukan hal yang sama push-line, tetapi pada tingkat prompt mana pun yang lebih rendah itu mengonversi seluruh perintah yang dimasukkan ke buffer multi-line. Dua fungsi hebat pada satu keybinding! Saya dapat merekomendasikan mengikat push-line-or-editbukan polos push-line. Anda tidak kehilangan apa-apa, dan mendapatkan fungsionalitas yang bermanfaat.
wjv
5

Selain ctrl- a ctrl- ktrik, jika Anda berada di layar, cukup ctrl- a duntuk melepaskan lalu pasang kembaliscreen -r

Anda juga bisa membuka jendela lain dengan ctrl+a c

warren
sumber
8
Jika Anda berada di layar, cukup buka jendela lain dengan Ctrl+A c.
Gilles
1
@Gilles .. kecuali Anda perlu menggunakan beberapa aspek dari status shell (variabel, fungsi, alias, dll.).
intuited
4

Cara alternatif, tidak sempurna, tekan Ctrl-X Ctrl-E. Ini akan membuka editor default Anda yang berisi perintah setengah mengetik Anda. Kemudian Anda dapat menyimpan perintah Anda ke file atau membuka shell baru dari dalam editor Anda. Ketika Anda keluar dari shell baru itu akan mengembalikan Anda ke editor dan menyimpan konten akan secara otomatis menjalankannya.

Ini tidak sempurna karena tidak mengembalikan Anda ke shell asli Anda, tetapi memaksa eksekusi perintah atau benar-benar membuangnya. Tetapi tidak ada pilihan sementara atau membunuh buffer yang perlu dikhawatirkan, dan ada juga beberapa penyesuaian yang bagus, misalnya jika 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
forcefsck
sumber
Alternatif yang sangat bagus. Saya vi-emacs-agnostic, jadi saya akan senang sebagai kerang menggunakan ini ketika powertools benar-benar dibutuhkan. (Ngomong-ngomong tentang vi, saya mencoba emulator linux N64 Mupen64Plus beberapa waktu lalu. Esc keluar dari emulator tanpa menyimpan. Saya segera menyerah memainkan apa pun.)
Lauritz V. Thaulow
1
@ lazyr, untuk menjalankan debian / ubuntu sudo update-alternatives --config editordan pilih editor favorit Anda. Untuk sistem lain atur variabel lingkungan EDITOR atau VISUAL ke editor favorit Anda, mis. Tambahkan export EDITOR=/usr/bin/nanodi .bashrc Anda.
forcefsck
3

Mirip dengan metode menambahkan #pada awal baris, ada metode yang bisa dibilang lebih sederhana yang saya gunakan yang tidak perlu kembali ke awal baris:

Cukup tambahkan kutipan terbuka dan jangan tutup, apakah tunggal atau ganda.

Lalu tekan Enter.

Lalu tekan CtrlC.

Perintah parsial disimpan dalam histori perintah (tersedia melalui panah atas) tetapi sebenarnya tidak dieksekusi.

Wildcard
sumber
2

Menggunakan zsh, jika Anda mengetik <ESC> q(melarikan diri, lalu Q), baris prompt Anda akan dipotong, sehingga Anda dapat mengetik perintah lain. Anda akan secara otomatis mendapatkan kembali teks terpotong Anda di prompt berikutnya.

Ia dapat mengingat beberapa baris pada saat yang bersamaan, sehingga Anda dapat menggunakannya saat sebuah garis sedang menunggu Anda. Anda bahkan dapat menggunakannya pada baris kosong untuk menunda resume dari garis potong Anda.

Ini bukan cara yang paling efisien jika Anda harus menggunakan beberapa perintah untuk pemeriksaan / persiapan (Anda harus mengetik ulang <ESC> qsebelum setiap perintah). Tapi saya pikir itu mungkin untuk mengikatnya ke jalan pintas yang lebih pendek.


Jika Anda hanya ingin memeriksa manual, ketik <ESC> h(escape, lalu H). Itu akan menjalankan run-helpbuilt-in, dengan kata pertama dari baris perintah sebagai argumen. Anda akan menemukan kembali garis Anda utuh setelah selesai.

loxaxs
sumber
Kebanyakan terminal akan membiarkan Anda melakukan M-qbukannya<ESC> q
sleblanc