Apakah ada cara untuk menjalankan perintah dari histori?

99

Sebagai contoh:

[root@ip-10-0-7-125 ~]# history | grep free
  594  free -m
  634  free -m | xargs | awk '{print "free/total memory" $17 " / " $ 8}'
  635  free -m
  636  free -m | xargs | awk '{print "free/total memory" $9 " / " $ 10}'
  736  df -h | xargs |  awk '{print "free/total disk: " $11 " / " $9}'
  740  df -h | xargs |  awk '{print "free/total disk: " $11 " / " $8}'
  741  free -m | xargs | awk '{print "free/total memory: " $17 " / " $8 " MB"}'

Saya hanya ingin tahu apakah ada cara untuk menjalankan perintah 636 tanpa mengetiknya lagi, cukup ketik sesuatu ditambah angka, seperti sejarah 636 atau sesuatu.

Yang satu
sumber
14
Anda tahu tentang ctrl-r?
Carlos Campderrós
1
Yap, saya tahu itu tapi bukan itu yang saya inginkan.
The One

Jawaban:

170

Dalam bash, hanya !636akan baik-baik saja.

pengguna164825
sumber
12
In Linux- Ini lebih berkaitan dengan shell (bash, zsh, dll) seseorang menjalankan OS yang Anda jalankan. Ada cangkang di linux tanpa dukungan untuk sejarah.
Zoredache
@Zoredache Dan juga, ini berfungsi dengan baik di sebagian besar implementasi bash di Windows.
Ajedi32
1
Bukan hanya bash, tentu saja, tetapi cangkang lain juga - termasuk csh.
Drew
5
Jika Anda memiliki perintah yang sangat mirip dengan apa yang ingin Anda jalankan, Anda dapat menambahkan :puntuk mencetak perintah tanpa menjalankannya, !636:pmisalnya. Yang berarti bahwa Anda dapat dengan mudah memilihnya lagi dari riwayat Anda dengan menekan panah atas dan membuat perubahan kecil yang Anda inginkan
AJefferiss
78

Ya, ini disebut "ekspansi sejarah." Lihat

LESS='+/^HISTORY EXPANSION' man bash

untuk detail lengkap.

Menggunakan tanda seru diikuti oleh angka bisa dibilang penggunaan paling sederhana:

!636

Namun, Anda juga dapat menjalankan perintah yang terakhir dieksekusi secara langsung tanpa mengetahui nomor riwayatnya:

!!

Atau Anda dapat menjalankan dua perintah kembali:

!-2

Namun, bentuk yang paling sering saya gunakan adalah mengulang argumen terakhir dari perintah terakhir:

echo this text goes into a file > /tmp/afile.txt
cat !$

Atau, katakanlah saya sedang memeriksa file. Menggunakan penyelesaian tab, saya mungkin melakukan hal berikut:

ls -l /really/long/path/to/some/file
less !$

Sekali lagi, baca halaman manual untuk lebih jelasnya:

LESS='+/^HISTORY EXPANSION' man bash
Wildcard
sumber
25
Secara interaktif, Alt-.bisa lebih nyaman daripada !$. Itu menyisipkan argumen terakhir dari perintah terakhir kata demi kata ke dalam baris.
ulidtko
2
@ulidtko Di mana pelarian khusus itu didokumentasikan (saya tahu !$, tetapi tidak pernah mendengar Alt-.)? Apakah Anda akan memposting tautan ke situ?
edmz
5
LESS="+/DEFAULT KEY BINDINGS" man 3 readline, /etc/inputrc, ~/.inputrc. Banyak program selain bash menggunakan libreadline; bagi yang melakukannya, Anda mendapatkan fitur yang sama seperti Alt-., Ctrl-X-U(batalkan), Ctrl-/(jelaskan pintasan), penyelesaian tab, dll - gratis. Misalnya, dengan hanya tiga baris dari PYTHONSTARTUPsatu dapat mengaktifkan tab-completion dan sejarah di REPL saham python . Yang akan bekerja (kebanyakan) sama dengan di bash, karena itu adalah pustaka GNU Readline yang bekerja. Halaman readline's menggambarkan fitur secara rinci.
ulidtko
2
Juga, Ctl-UpArrow (atau AltUpArrow on bash) akan bergulir mundur melalui daftar riwayat. Mengetik beberapa karakter kemudian UpArrow hanya mendapatkan perintah yang dimulai dengan huruf itu, misalnya "fr (Ctl-Up)" menggulir semua perintah "bebas ..." dalam daftar OP. Ini juga berfungsi dalam hal-hal seperti gnuplot & gdb yang menggunakan readline.
jamesqf
2
@ Ajedi32, lihat baris tebal terakhir dalam jawaban saya. :) Sejujurnya, jawaban ini hampir tidak terasa seperti apa yang bisa dilakukan ekspansi sejarah . Perlu diingat bahwa ini berada pada level shell, bukan perintah yang Anda panggil; maka echo {1..5}diikuti oleh touch !$akan menyentuh lima file, bukan hanya satu. Jadi sebenarnya itu bukan argumen terakhir tetapi kata terakhir di baris itu. (Coba juga echo hello >tempdiikuti oleh echo goodbye !$.) Jika Anda dapat memikirkan cara untuk membuatnya lebih jelas, bebas untuk menyarankan edit.
Wildcard
14

Yang bagus, jika Anda tidak ingin riwayat pertama, catat nomornya, dll:

di bash (dan mungkin yang lain):

ctrl-r something 

( ctrl-r= "membalikkan pencarian secara interaktif") ( something= bagian dari perintah sebelumnya)

Ini akan menampilkan baris riwayat terbaru yang berisi something. Untuk mendapatkan yang sebelumnya, lakukan ctrl-r (sendiri) lagi, setiap kali mendapat baris sebelumnya.

ex:

ctrl-r  10

untuk menampilkan baris riwayat terbaru yang berisi '10' (untuk contoh baris dengan $10, dalam contoh Anda), dan ctrl-rlagi sampai Anda mengambil baris riwayat yang Anda cari

Ketika garis yang Anda inginkan muncul, hanya Enteruntuk menjalankannya (atau Anda juga bisa mengeditnya, menggunakan arrow keys, backspacedan ctrl-auntuk pergi ke awal baris, ctrl-euntuk sampai ke Akhir, ctrl-k: untuk "membunuh" dari kursor ke akhir baris (= menghapus + menyimpannya dalam buffer),: ctrl-yuntuk mengembalikan, dari buffer, bit yang sebelumnya mati, dll.)

Jika Anda ingin mencari maju (ctrl-s), Anda harus terlebih dahulu menonaktifkan XON : lihat https://stackoverflow.com/a/791800/1841533 :

"hanya untuk menonaktifkan XON / XOFF dengan menjalankan

stty -ixon

"(dan kemudian Anda akan dapat menggunakan ctrl-s, tanpa harus membekukan terminal)

Olivier Dulac
sumber
Jika saya melakukan ini dan secara tidak sengaja menekan ctrl-r terlalu banyak, apakah ada cara untuk mencari lagi dalam sejarah?
kasperd
@kasperd: Ya, Anda bisa. banyak jawaban pada se menunjukkannya: ctrl-s untuk pencarian maju.
Olivier Dulac
Sayangnya ctrl-s digunakan untuk membekukan terminal, dan bash tidak menonaktifkannya, sehingga tidak berfungsi dalam konfigurasi default. (Program lain - seperti emacs - menonaktifkan keybinding untuk membekukan terminal sehingga ctrl-s dapat digunakan untuk pencarian.)
kasperd
@kasperd: Ya, maaf karena tidak menyebutkannya sebelumnya (saya menunjuk "banyak jawaban" karena mereka melakukan hal itu, tapi saya tidak meluangkan waktu untuk mengetik ini di komentar atau memberikan tautan ... (Saya menggunakan saya telepon) .Saya sekarang kembali ke rumah dan dapat mengeditnya dalam jawaban di atas. ctrl-s untuk pencarian bash history mengharuskan Anda untuk stty -ixon terlebih dahulu
Olivier Dulac
Perintah itu akan menghentikan penggunaan normal ctrl-s, jadi itu bukan pilihan.
kasperd
7

Anda dapat menggunakan shell builtin fc :

fc -s 636
Steven Penny
sumber
2
Ini sebenarnya lebih baik daripada jawaban yang diterima, tetapi Anda harus menghapus -suntuk mendapatkan manfaatnya. Jika Anda menjalankan, fc 636Anda akan membuka editor dengan perintah 636 dari riwayat Anda di buffer, dan ketika Anda menyimpan dan keluar dari perintah (dimodifikasi atau tidak) akan dijalankan. Dan yang lebih baik lagi, yang satu ini kompatibel dengan POSIX .
Wildcard
@SvenvenPenny Terima kasih. Dan ya, saya tahu apa itu POSIX, meskipun saya tidak melihat relevansinya. Bagaimanapun, beberapa dokumentasi yang mudah diakses dan disertakan akan menyenangkan.
Faheem Mitha
@FaheemMitha coba jalankan "help fc."
Wildcard
@Wildcard helpbukan POSIX - mungkin harus melakukan man dashatau serupa
Steven Penny
@ Kartu Ucapan Terima kasih. Saya cenderung lupa helpada. Shell lain builtin. Dan membingungkan bagi pengguna yang tidak waspada yang mungkin ingin membantu dengan sistem baru, tetapi sebaliknya dihadapkan dengan aliran omong kosong. :-(
Faheem Mitha
3

Ada HSTR- hhperintah untuk bashdan zshpemilihan perintah interaktif, lebih baik daripada pencarian terbalik Ctrl-R:

contoh perintah sejarah interaktif

bersifat interaktif, sehingga Anda dapat mencari, dan mengedit perintah, sebelum menjalankannya.

Di Ubuntu, Anda dapat menginstal hhdengan satu-liner berikut:

sudo add-apt-repository ppa:ultradvorka/ppa && sudo apt-get update && sudo apt-get install hh && hh --show-configuration >> ~/.bashrc

atau langkah demi langkah:

sudo add-apt-repository ppa:ultradvorka/ppa
sudo apt-get update
sudo apt-get install hh

Instal hhdi Fedora, RHEL atau CentOS:

sudo dnf|yum install hstr -y

Di macOS dengan homebrew:

brew install hh

... lalu konfigurasikan dengan:

hh --show-configuration >> ~/.bashrc

Ini akan menggantikan perilaku Ctrl-R default.

Jalankan hh --show-configurationuntuk menentukan apa yang akan ditambahkan ke profil Bash Anda.

Opsi konfigurasi lainnya tersedia di beranda proyek di Github: https://github.com/dvorka/hstr

modlin
sumber