Cari perintah sebelumnya dengan awalan yang baru saja saya ketik

67

Kita dapat menggunakan panah atas dan bawah untuk menavigasi dalam sejarah perintah.

Dalam beberapa IDE, seperti Matlab, jika kita memasukkan sesuatu dan kemudian tekan tombol panah, kita gulir hanya di antara perintah sejarah dimulai dengan apa yang kita masukan. Itu benar-benar nyaman, tetapi di terminal shell, ini tidak berhasil.

Apakah ada cara untuk mendapatkan fungsi serupa di terminal shell? Dan ada tips lain untuk meningkatkan efisiensi dalam penggunaan terminal?

Lee
sumber
Anda cukup menggunakan shell yang menyediakan fitur seperti itu, seperti fish;)
yoann
@Anda Anda menganggap bash tidak. Itu, melalui readline, tidak dapat diakses secara default.
muru
@uru Saya tahu CTRL + R dalam bash, dan jawaban egmont memberikan cara yang rapi untuk melakukannya dengan Page Up / Page Down. Apakah ada cara untuk melakukannya dengan tombol panah?
yoann
1
@yoann, periksa unix.stackexchange.com/a/76591/70524 . Alih-alih \e[5~dan \e[6~, penggunaan \e[A, \e[B.
muru

Jawaban:

95

Apa yang Anda cari adalah CtrlR.

Ketik CtrlRlalu ketikkan bagian dari perintah yang Anda inginkan. Bash akan menampilkan perintah pertama yang cocok. Terus mengetik CtrlRdan bash akan menggilir perintah yang cocok sebelumnya.

Untuk mencari mundur dalam sejarah, ketik CtrlSsaja. (Jika CtrlStidak bekerja seperti itu untuk Anda, kemungkinan itu berarti bahwa Anda perlu menonaktifkan XON / XOFF flow control: untuk melakukan itu, jalankan stty -ixon.)

Ini didokumentasikan di bawah "Pencarian" di man bash.

John1024
sumber
1
Ctrl-Quntuk keluar dari keadaan beku, jika Anda telah menekan Ctrl-Stanpa mematikan kontrol aliran terlebih dahulu dan membuat terminal Anda beku.
HongboZhu
26

Tempatkan ini di Anda ~/.inputrc:

"\e[5~": history-search-backward
"\e[6~": history-search-forward

Ini membuat Page Updan Page Downberperilaku seperti yang Anda inginkan. (Beberapa distribusi sudah mengkonfigurasinya untuk Anda.) Saya pribadi menemukan cara ini lebih nyaman daripada Ctrl+ Ratau history.

egmont
sumber
Ini adalah cara paling nyaman dalam semua jawaban saat ini. Bisakah Anda memberi sedikit penjelasan tentang mekanisme kerja?
Lee
3
~/.inputrcatau /etc/inputrcatau file yang dirujuk oleh variabel lingkungan $INPUTRCadalah file konfigurasi pengeditan baris semua aplikasi menggunakan readline, termasuk bash (shell Anda). Ia memiliki kemampuan pengeditan baris bawaan tertentu, termasuk keduanya: dalam pencarian halaman manual bash untuk salah satu kata kunci ini untuk mengetahui lebih lanjut. \e[5~/ \e[6~adalah urutan pelepasan yang dihasilkan oleh tombol Page Up / Down di sebagian besar emulator terminal; untuk melihatnya, jalankan catperintah dan kemudian tekan tombol-tombol ini (byte melarikan diri diwakili di terminal sebagai ^[, di inputrc sebagai \e).
egmont
Contoh dalam pertanyaan awal Anda mengatakan bahwa tombol Atas / Bawah berfungsi seperti ini di Matlab. Akan menarik untuk melihat apa yang terjadi jika Anda menempatkan urutan Atas dan Bawah dalam inputrc dan menetapkan untuk tindakan ini; apakah itu akan bekerja dengan benar, atau memiliki efek samping yang buruk karena bertentangan dengan perilaku default mereka. Saya tidak tahu, saya akan senang mendengar temuan Anda jika Anda bereksperimen dengan ini.
egmont
Ketika saya melakukannya echo $INPUTRCitu kosong. Saya menggunakan Ubuntu 14.04
JorgeeFG
2
Saya pribadi lebih suka mengesampingkan panah atas dan bawah untuk melakukan ini: "\e[A": history-search-backwarddan"\e[B": history-search-forward
A.Wan
9

Selain riwayat ^ r / ^ i-search:

alt.menyisipkan "kata" terakhir dari perintah sebelumnya di kursor. Ulangi untuk mendapatkan kata terakhir dari perintah yang lebih lama. (Tetapi perhatikan bahwa trailing &dianggap sebagai kata terakhir untuk perintah latar belakang).

Ini sangat berguna untuk mkdir foo, cdalt-dot. Bahkan lebih cepat daripada panah atas, ^ a, alt-d (hapus kata depan) cd,.

Untuk mendapatkan kata ke-2 ke terakhir, gunakan esc - 2 alt+.(yaitu gunakan argumen numerik gaya emacs untuk alt+.. Negatif dihitung dari akhir, jumlah positif maju dari awal.) Tapi ini biasanya lebih banyak masalah daripada nilainya; pada titik tertentu lebih cepat untuk meraih mouse dan salin / tempel, atau panah atas dan ^ w / ^ y bagian dari itu (lihat di bawah).


Jika terminal Anda diatur dengan baik / benar, ctrl-kiri dan ctrl-kanan akan mundur / maju dengan kata-kata. Jika tidak, semoga setidaknya alt-b dan alt-f akan melakukan hal yang sama.


ctrl- / adalah undo. Anda dapat menggunakan pengulangan otomatis untuk menghapus kata-kata jauh lebih efisien jika Anda dapat membatalkan ketika Anda melakukan overshoot sedikit.


Pencampuran / pencocokan perintah yang lebih kuat berasal dari penggunaan kill-ring, yang berfungsi seperti di Emacs. ctrl-y untuk menempelkan ctrl-w / ctrl-u / ctrl-backspace / alt-d terakhir. alt-y untuk menggilir teks yang sudah lama dibunuh.

Beberapa ctrl-w atau apa pun secara berturut-turut dibuat pada entri kill-ring. Gunakan panah kiri dan kanan atau sesuatu untuk memecah entri jika Anda ingin menghapus dua hal dan hanya menempel satu di kemudian hari.

Menggabungkan semua ini bersama-sama, Anda bisa

  • mulai mengetik perintah
  • ctrl-r untuk kembali ke perintah lama dan ambil bagiannya dengan control-w atau serupa.
  • esc-r atau alt+rmengembalikannya seperti sebelum Anda menghapusnya.
  • alt >untuk pergi ke akhir sejarah (yaitu panah ke bawah sepanjang jalan), untuk kembali ke perintah Anda berada di tengah.

Kiat penggunaan interaktif lainnya:

Aktifkan shopt -s globstar, sehingga Anda dapat melakukan **/*.c(rekursif termasuk direktori saat ini). Terkadang berguna untuk penggunaan interaktif, tetapi biasanya find -name '*.c' -exec foo {} +lebih baik.

Jika Anda menulis skrip bash, Anda juga akan merasa mudah untuk shopt -s extglobmengaktifkannya di shell interaktif. Terkadang Anda akan menemukan penggunaan untuk hal-hal seperti *.!(c|h)mencocokkan file yang tidak berakhir dengan .c atau .h.

Cari alias yang Anda suka untuk ls -l, lessdan apa pun yang Anda lakukan banyak. ( cp -i,, mv -idan rm -Ibagus. Jangan terbiasa bergantung pada mereka untuk melakukan rm selektif. GNU rm's -Saya meminta sekali untuk semua argumen.)

Saya suka alias m=less(m untuk "lebih"). Saya telah lessmengatur ,dan .terikat dengan file sebelumnya / berikutnya ( lesskey). Standarnya adalah urutan multi-penekanan tombol yang tidak dapat digunakan dengan pengulangan otomatis.


Saya suka melakukan semua yang ada di dalam layar GNU. Saya merasa lebih mudah untuk melacak jendela layar bernomor daripada muatan kapal di Konsole (atau emulator terminal lain yang pernah saya coba). Jika Anda belum mengetahuinya screen, pelajari tmux karena lebih baru dan lebih halus.

Untuk mendapatkan sesuatu seperti fungsi membuka shell baru dengan cwd yang sama seperti shell lain, saya menggunakan hook kustom untuk cd / pushd / popd yang memungkinkan saya lakukan cds 8untuk cd ke apa pun dir shell saya di jendela layar 8 gunakan. Ini berfungsi bahkan untuk shell di luar sesi layar, selama hanya ada satu sesi layar.

Peter Cordes
sumber
Milik saya tampaknya tidak "dikonfigurasikan dengan benar". Banyak cara pintas yang saya lihat di sini tidak berfungsi, saya menggunakan Terminal stok dari Ubuntu 14.04. Bagaimana saya bisa mengkonfigurasinya?
JorgeeFG
@JorgeeFG: Saya pikir itu bekerja untuk saya di luar kotak dengan gnome-terminaldi Ubuntu 14,04, sebelum saya beralih ke KDE. Opsi yang relevan ada di pengaturan terminal Anda, awalan esc vs bit tinggi, dan mungkin beberapa pengaturan lainnya. Beberapa dari mereka tidak bekerja dengan sempurna untuk saya melalui ssh. (mis. ctrl kiri / kanan mengurung kode escape untuk tombol panah, dan saya 5Dmuncul secara harfiah)
Peter Cordes
7

Tambahkan baris berikut ke ~/.inputrc

"\e[A": history-search-backward
"\e[B": history-search-forward

Ini mirip dengan jawaban egmont, tetapi alih-alih menggunakan Page Up dan Page Down, ia menggunakan urutan escape untuk Arrow Up dan Arrow Down. Cara ini jauh lebih nyaman digunakan pada Mac.

John Slavick
sumber
4

Saya selalu cenderung mengkonfigurasi mesin saya dengan nilai HISTSIZE besar sehingga menyimpan daftar sejarah yang lebih lama, serta HISTTIMEFORMAT dengan nilai cap waktu sehingga saya dapat melihat kapan perintah dijalankan.

export HISTSIZE=10000
export HISTTIMEFORMAT="%m/%d/%Y %T "
Alpha01
sumber
3

Cara yang biasanya saya gunakan adalah menggabungkan historyperintah dengangrep

YAITU:

history | grep <command im looking for>

Itu akan menampilkan riwayat nomor perintah yang Anda ketikkan yang berisi perintah itu, Anda kemudian dapat menggunakan:

!<number listed in history command>

untuk mengulangi perintah itu.

YAITU:

history | grep history

142  history
143  history | grep lvresize
568  history | grep echo
570  history | grep echo
571  history | grep history

diikuti oleh: !571

akan berulang history | grep history

Saus
sumber
1
CR = lebih baik + lebih aman
PSkocik
1
Mungkin, secara pribadi saya menemukan sejarah yang disalurkan untuk mencoba menjadi cara yang lebih cepat untuk menemukan sebagian besar perintah. Sejauh Lebih Aman, saya tidak yakin apa yang Anda maksud, apa risiko yang melekat dalam menggunakan riwayat yang seharusnya dicari melalui dengan cR?
Gravy
2
@ Gravy Saya menduga PSkocik berarti !penggantian riwayat kurang aman.
derobert
3
@ Gravy Risiko yang melekat akan secara tidak sengaja mendapatkan garis yang salah. Tidak tahu mengapa terminal Anda telah dibekukan, kecuali jika Anda menggunakan Control-S dan Anda memiliki kontrol aliran xon / xoff diaktifkan (seringkali default). Jika demikian, Control-Q akan mengembalikannya.
derobert
1
Saya setuju dengan @PSkocik, cr jauh lebih baik karena lebih mudah untuk mengedit baris histori, daripada hanya menjalankannya lagi dengan cara yang sama. Menjalankan perintah yang persis sama lagi adalah kasus sepele dari apa yang dapat Anda lakukan untuk menghemat waktu mengetik ulang variasi pada one-liners yang kompleks, atau melengkapi file yang berbeda di jalur yang panjang. Lihat jawaban saya.
Peter Cordes
1

Saya menggunakan 4 tips setiap hari (dan beberapa lainnya) di terminal bash saya:

  • Jalankan perintah terakhir: !!

  • Jalankan perintah N dari sejarah: !N

  • Cetak perintah terakhir dimulai dengan awalan dari sejarah: !prefix:p

  • Jalankan perintah terakhir dimulai dengan awalan dari sejarah: !prefix

Nolwennig
sumber
1

Jika tidak apa-apa bagi Anda untuk menggunakan zshalih-alih bashAnda menggunakan cona gunakan oh-my-zsh untuk itu.

Ini berisi panah panah atas navigasi melalui riwayat perintah Anda. Hal ini memungkinkan juga, navigasi yang sama ketika Anda sudah mengetik teks (seperti Mathlab).

sunting: Ini juga berisi hal-hal lain yang berfokus pada pengembang, seperti alias dan tema. Tambahan itu membuat distro lebih besar dan lebih kompleks untuk digunakan.

https://github.com/robbyrussell/oh-my-zsh

pengguna9869932
sumber
1
oh-my-zshberisi banyak barang. Anda mungkin juga mengatakan: Fitur persis ini termasuk dalam distro itu, ketika semua yang Anda butuhkan adalah pengaturan atau aplikasi tertentu.
muru
Saya mengedit posting: Saya memperingatkan bahwa ini lebih besar dari aplikasi sederhana.
user9869932
1

Tambahkan alias berikut ke ~ / .bashrc

alias h='history | awk '"'"'{$1="";print}'"'"' |sed "s/^ *//" |grep -v "^h " | sort | uniq | grep'

Penggunaan: h fireakan memberi saya daftar perintah berisi api . atau h ^fireakan membuat saya daftar perintah mulai dengan api .

Ini berguna ketika saya ingin melihat serangkaian perintah secara bersamaan.

Omong-omong, '"'"'jelek tapi saya tidak bisa menemukan cara lain untuk menghindari tanda kutip tunggal dalam tanda kutip tunggal.

Hosi Golden
sumber
fyi - h="history | awk '{\$1=\"\"; print}'harus bekerja. alternatifnya buat fungsi dan panggil itu.
DarkHeart
terima kasih DarkHeart, tapi saya mencoba kode Anda, ternyata tidak berfungsi di lingkungan saya, mungkin ada sesuatu yang berbeda pada saya
Hosi Golden