Bagaimana cara menjalankan perintah berurutan dari histori?

49

Misalkan saya ingin menjalankan urutan empat perintah yang telah saya jalankan sebelumnya. Jika yang pertama adalah 432 dalam sejarah perintah, maka saya bisa melakukan:

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

Saya ingin tahu, apakah ada cara yang lebih efisien untuk mencapai ini?

Eric Wilson
sumber
1
Bukan memposting ini sebagai jawaban karena tidak menjalankan perintah, tetapi Anda bisa mengetik history -p \!43{2..5}untuk mencetak perintah 432 hingga 435 ke terminal, cocok untuk salin / tempel berikutnya.
Wildcard

Jawaban:

48

Jika mengacu pada perintah yang baru saja dijalankan, cara yang lebih efisien adalah merujuknya dengan angka negatif:

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

Juga, setelah Anda melakukannya, entri riwayat terakhir Anda akan berisi seluruh rantai perintah, sehingga Anda dapat mengulanginya !!.


Sunting: Jika Anda belum melakukannya, kenallah dengan fungsi bawaan yang hebat fc, yang disebutkan oleh Gilles . (Gunakan help fc.) Ternyata Anda juga dapat menggunakan angka negatif, sehingga Anda dapat melakukan hal yang sama seperti menggunakan di atas

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

Ini memiliki satu peringatan, meskipun: setelah ini, evalbaris disimpan dalam sejarah sebagai perintah terakhir. Jadi jika Anda menjalankan ini lagi, Anda akan jatuh ke lingkaran!

Cara yang lebih aman untuk melakukan ini adalah dengan menggunakan fcmode operasi default : meneruskan kisaran perintah yang dipilih ke editor dan menjalankannya setelah Anda keluar dari sana. Mencoba:

 fc -4 -1

Anda bahkan dapat membalik urutan kisaran perintah: fc -1 -4

rozcietrzewiacz
sumber
Saya baru saja membaca apa yang saya tulis ... LOL. Sebenarnya, saya tidak yakin tentang reinvoke ( mungkin meminta kembali ?), Tapi terima kasih sudah memberi tahu :) Saya selalu menghargai koreksi.
rozcietrzewiacz
Scrabblefinder.com mengatakan reinvoke adalah kata Scrabble yang valid. Tidak bisa mendapatkan yang lebih pasti dari itu. :)
BentFX
1
Dengan jawaban yang bagus seperti ini (+1), tidak masalah bagaimana Anda mengejanya; terutama karena bentuk ejaan tidak muncul dalam 3 kamus bahasa Inggris utama : Oxford, Camgridge, Merriam-Webster (Saya akan memilih tanda hubung)
Peter.O
34

Untuk melihat rentang perintah dalam riwayat, gunakan fcperintah bawaan:

fc -ln 432 435

Untuk mengeksekusi mereka lagi:

eval "$(fc -ln 432 435)"
Gilles 'SANGAT berhenti menjadi jahat'
sumber
4
Sangat bagus. Saya ingin tahu, mengapa man fctidak memberi saya apa-apa. Apa artinya fc? Opsi apa lagi yang ada?
Eric Wilson
2
@ Eric Wilson ... ketik help fc... dan juga help help.... help: help [-dms] [pattern ...] Tampilkan informasi tentang perintah builtin.
Peter.O
Saya baru saja kembali ke sini, mencari jawaban Anda. Ini benar-benar builtin hebat! Terutama ketika Anda adalah fungsi default-nya - meminta editor untuk mengubah serangkaian perintah yang akan diputar ulang. Terima kasih, Gilles.
rozcietrzewiacz
1
Tanpa -lbendera, itu akan dieksekusi tanpa perlu kejahatan eval.
Bernhard
1
@EricWilson Sebuah pencarian google membawa saya ke "Unix pendeknya" buku yang mengatakan fcsingkatan dari "menemukan perintah" atau "perintah memperbaiki".
Slothworks
10

Ada cara yang bagus dan alternatif untuk menjalankan sejumlah perintah secara berurutan dari sejarah Bash:
alih-alih menggunakan pengganti sejarah ( !432atau !-4), Anda dapat mencari di seluruh sejarah dengan Ctrl+ r, dan setelah Anda menemukan perintah pertama yang ingin Anda gunakan jalankan, tekan Ctrl+ o( operasikan-dan-dapatkan-berikutnya ) alih-alih returntombol
ini akan meluncurkan perintah dan mengusulkan yang berikutnya dari sejarah. Anda dapat menekan Ctrl+owaktu sebanyak yang Anda inginkan, dan mengakhiri urutan baik dengan returnyang terakhir, atau Ctrl+cberhenti tanpa meluncurkannya.

Cyril Chaboisseau
sumber
Hmm, setelah saya tekan Ctrl-oitu hanya menghasilkan literal ^odan istirahat saya (reverse-i-search). Mungkin ada beberapa pengaturan lain yang terlibat.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
8

Untuk menjalankan perintah dengan segera daripada mengeditnya, berikut adalah versi Giles yang secara sintaksis lebih tipis menggunakan eval :

fc -e: 432 435

Argumen usus besar ke -e adalah bash noop, yang memiliki efek melewatkan langkah "buka di editor" yang diinginkan fc. Juga, sekarang histori (baru-baru ini) akan berisi perintah aktual dari histori, bukan pernyataan eval.

pengguna1543542
sumber
0

fc untuk loop dan xsel

Ini berfungsi dengan baik ketika saya ingin menggabungkan dan menjalankan kembali perintah n terakhir beberapa kali:

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})"
)

Kemudian:

$ 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

Atau untuk perintah yang lebih besar yang mungkin perlu diedit:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
sumber