Apakah ada jalan pintas untuk menjalankan serangkaian perintah dalam bash history?

20

Misalkan saya memiliki contoh sepele berikut di history:

...
76 cd ~
77 ./generator.sh out.file
78 cp out.file ~/out/
79 ./out/cleaner.sh .
80 ls -alnh /out
...

Jika saya ingin menjalankan perintah 77,, 78dan 79dalam satu perintah, apakah ada jalan pintas untuk ini? Saya sudah mencoba !77 !78 !79, yang hanya akan menempatkan mereka semua pada satu baris untuk dieksekusi.

MrDuk
sumber
9
Tidak !77 ; !78 ; !79apa-apa
thrig
1
Saya kira apa pun yang mengetik baris demi baris tidak apa-apa, tetapi berharap untuk sesuatu yang lebih ringkas (di sepanjang baris !77-79)
MrDuk
1
@ MrDuk, anak laki-laki melakukan itu butuh waktu untuk mengingat. Lihat jawaban saya yang diperbarui untuk solusi yang sangat ringkas ! :)
Wildcard
Ajaib! :)
MrDuk

Jawaban:

28

Sunting: Anda dapat melakukan ini dengan cara yang sesuai dengan POSIX dengan alat perintah perbaikanfc :

fc 77 79

Ini akan membuka editor Anda (mungkin vi) dengan perintah 77 hingga 79 di buffer. Saat Anda menyimpan dan keluar ( :x), perintah akan dijalankan.


Jika Anda tidak ingin mengeditnya dan Anda SANGAT PASTI Anda tahu perintah mana yang Anda panggil, Anda dapat menggunakan:

fc -e true 77 79

Ini digunakan truesebagai "editor" untuk mengedit perintah, sehingga hanya keluar tanpa membuat perubahan dan perintah dijalankan apa adanya.


JAWABAN ASLI:

Anda dapat gunakan:

history -p \!{77..79} | bash

Ini mengasumsikan bahwa Anda tidak menggunakan alias atau fungsi atau variabel apa pun yang hanya ada di lingkungan eksekusi saat ini, karena tentu saja itu tidak akan tersedia di shell baru yang sedang dimulai.


Solusi yang lebih baik (terima kasih kepada Michael Hoffman karena mengingatkan saya pada komentar) adalah:

eval "$(history -p \!{77..79})"

Salah satu dari sangat, sangat sedikit kasus di mana evalsebenarnya sesuai!


Lihat juga:

Wildcard
sumber
2
Ini tidak akan bekerja dengan benar jika ada perintah yang mengubah lingkungan eksekusi saat ini, misalnya dengan mengubah variabel atau melakukan cd, tetapi itu adalah kasus tepi.
G-Man Mengatakan 'Reinstate Monica'
3
eval "$(history -p \!{77..79})"harus bekerja.
Michael Hoffman
1
@MichaelHoffman, saya telah memikirkan hal itu dan berpikir saya telah mencobanya, tetapi saya baru sadar bahwa saya tidak mengutip! Doh! Tidak heran itu tidak berhasil ... mengedit jawaban sekarang.
Wildcard
14

Jawaban sederhana: alih-alih !77 !78 !79,

  • ketik !77; !78; !79untuk melakukan apa yang Anda coba lakukan - jalankan perintah 77, dan kemudian perintah 78, lalu perintah 79, tanpa syarat, atau
  • ketik !77 && !78 && !79 untuk mengeksekusi perintah 77 dan periksa apakah berhasil. Dan kemudian, jika perintah 77 berhasil, jalankan perintah 78. Dan kemudian, jika perintah 78 berhasil, jalankan perintah 79.

Jawaban yang sedikit lebih pintar (jika Anda berada di jendela tipe terminal):

  • Cari tahu nomor perintah apa yang akan Anda ketik selanjutnya.
    • Dimungkinkan untuk memasukkan ini dalam prompt Anda; Saya percaya itu dengan memasukkan \!di Anda PS1.
    • Atau lihat daftar riwayat Anda. Jika entri terakhir adalah 82 history, maka perintah Anda berikutnya adalah 83.
  • Kurangi 83−77 = 6.
  • Jenis !-6. Ini akan kembali menjalankan perintah 77.
  • Pilih !-6, salin, dan tempel. Karena eksekusi ulang Anda dari perintah 77 ( ./generator.sh) adalah perintah 83, Anda sekarang berada di perintah 84, sehingga !-6akan kembali menjalankan perintah 78.
  • Ulangi menempelkan !-6seperti yang diinginkan.
G-Man Mengatakan 'Reinstate Monica'
sumber