Di bash, bagaimana cara mengikat tombol fungsi ke sebuah perintah?

91

Contoh: Saya ingin mengikat F12kunci ke perintah echo "foobar"sedemikian rupa sehingga setiap kali saya menekan F12pesan "foobar" akan dicetak ke layar. Idealnya, ini bisa berupa perintah shell sembarang, bukan hanya bawaan. Bagaimana seseorang melakukan ini?

SiegeX
sumber

Jawaban:

164

Anda dapat menentukan urutan karakter yang dikeluarkan oleh sebuah tombol dengan menekan Ctrl- vpada baris perintah, lalu menekan tombol yang Anda minati. Di sistem saya untuk F12, saya mengerti ^[[24~. The ^[mewakili Esc. Jenis terminal atau emulator terminal yang berbeda dapat mengeluarkan kode yang berbeda untuk kunci yang sama.

Pada prompt Bash Anda dapat memasukkan perintah seperti ini untuk mengaktifkan makro kunci sehingga Anda dapat mencobanya.

bind '"\e[24~":"foobar"'

Sekarang, saat Anda menekan F12, Anda akan mendapatkan "foobar" pada baris perintah yang siap untuk pengeditan lebih lanjut. Jika Anda ingin menekan tombol untuk segera memasukkan perintah, Anda dapat menambahkan baris baru:

bind '"\e[24~":"pwd\n"'

Sekarang ketika Anda menekan F12, Anda akan mendapatkan direktori saat ini ditampilkan tanpa harus menekan Enter. Bagaimana jika Anda sudah mengetik sesuatu di baris dan Anda menggunakan ini yang secara otomatis dijalankan? Itu bisa jadi berantakan. Namun, Anda dapat menghapus garis sebagai bagian dari makro Anda:

bind '"\e[24~":"\C-k \C-upwd\n"'

Spasi tersebut memastikan bahwa Ctrl- umemiliki sesuatu untuk dihapus agar bel tidak berbunyi.

Setelah Anda membuat makro berfungsi seperti yang Anda inginkan, Anda dapat membuatnya tetap dengan menambahkannya ke ~/.inputrcfile Anda . Tidak perlu bindperintah atau kumpulan tanda kutip tunggal terluar:

"\e[24~":"\C-k \C-upwd\n"

Edit:

Anda juga dapat membuat pengikatan kunci yang akan mengeksekusi sesuatu tanpa mengganggu baris perintah saat ini.

bind -x '"\eW":"who"'

Kemudian saat Anda mengetik perintah yang membutuhkan nama pengguna, misalnya, dan Anda perlu mengetahui nama pengguna yang masuk, Anda dapat menekan Alt- Shift- Wdan output dari whoakan ditampilkan dan prompt akan dikeluarkan kembali dengan perintah parsial Anda utuh dan kursor berada pada posisi yang sama di baris.

Sayangnya, ini tidak berfungsi dengan baik untuk kunci seperti F12yang menghasilkan lebih dari dua karakter. Dalam beberapa kasus, hal ini dapat diatasi.

Perintah ( whodalam hal ini) dapat berupa apa saja yang dapat dieksekusi - program, skrip, atau fungsi.

Dijeda sampai pemberitahuan lebih lanjut.
sumber
2
Bagaimana jika saya ingin menambahkan pengikatan ke "ctrl + q"?
kubudi
5
@kubudi: bind '"\C-q": menu-complete'misalnya (atau di ~/.inputrc: Anda "\C-q": menu-complete). Anda juga mungkin perlu stty -ixondi Anda ~/.bashrcuntuk kontrol aliran menonaktifkan dan make ^ S dan ^ Q yang tersedia.
Dijeda sampai pemberitahuan lebih lanjut.
Anda mengatakan itu ^[mewakili escdan kemudian Anda tampaknya menggantikannya \edalam contoh Anda. Bisakah Anda menjelaskan mengapa?
Remover
1
@Remover: Ini ^[adalah representasi keluaran. Ini \eadalah salah satu cara untuk memasukinya ( ^[tidak berfungsi untuk itu).
Dijeda sampai pemberitahuan lebih lanjut.
Bagaimana cara mengikat "\ Cz"? Saya ingin mendapatkan sesuatu seperti yang dijelaskan untuk zsh di sheerun.net/2014/03/21/how-to-boost-your-vim-productivity
pkoch
19

Anda dapat menentukan pengikatan kunci bash di ~/.inputrc (file konfigurasi untuk pustaka GNU Readline). Sintaksnya adalah

<keysym atau nama kunci>: makro

sebagai contoh:

Control-o: "> output"

akan membuat makro yang memasukkan "> keluaran" saat Anda menekan ControlO

 "\e[11~": "echo foobar"

akan membuat makro yang menyisipkan "echo foobar" ketika Anda menekan F1... Saya tidak tahu untuk apa keysym F11itu begitu saja.

Edit:

.inputrcmemahami \nurutan escape untuk linefeed, sehingga Anda bisa menggunakannya

 "\e[11~": "echo foobar\n"

Yang secara efektif akan 'tekan enter' setelah perintah dikeluarkan.

Barton Chittenden
sumber
4
Anda dapat menggunakan "\ n" dalam makro, untuk menambahkan karakter baris baru:
Barton Chittenden
Ini bekerja lebih baik bagi saya karena mendefinisikan pemetaan kunci saat membuka terminal.
Heldraug
Untuk Alt, gunakan \e, misalnya "\eo": "> output".
Jānis Elmeris
Untuk tutorial yang lebih mendalam tentang penggunaan, .inputrclihat hackaday.com/2018/01/19/linux-fu-custom-bash-command-completion
Josh Habdas
1
@ArthurHenriqueDellaFraga Saya telah mengedit jawabannya; itu akan ada di direktori home Anda. Jika tidak ada, Anda dapat membuatnya.
Barton Chittenden
7

Solusi ini khusus untuk lingkungan X11 dan tidak ada hubungannya dengan bash, tetapi menambahkan yang berikut ini ke .Xmodmaps Anda

 % loadkeys
 keycode 88 = F12
 string F12 = "foobar"
 %

akan mengirim string "foobar" ke terminal setelah menekan F12.

Wesley Rice
sumber
Perlu diingat bahwa ini tidak sama dengan shell yang menjalankan perintah. Jika Anda benar-benar ingin menjalankan perintah, Anda harus menekan enter (atau meminta string yang dikirim melakukannya untuk Anda). Mungkin juga ingin aman dan bersihkan garis dulu.
Kaskabel
2
Ini akan luar biasa, tetapi tampaknya tidak berfungsi pada Fedora 20. Saya bahkan mencoba menggunakan xev untuk menemukan kode kunci yang tepat untuk F12 terlebih dahulu (dalam kasus saya, 96) dan menggunakannya sebagai ganti 88. Tidak ada yang berfungsi.
BobDoolittle
2

Saya ingin terikat Ctrl+Bpada sebuah perintah. Terinspirasi oleh jawaban di atas, saya mencoba menggunakanbind tetapi tidak dapat menemukan rangkaian coretan samar ( \e[24~?) Yang diterjemahkan keCtrl+B .

Di Mac, buka Pengaturan aplikasi Terminal, Profil -> Keyboard -> +lalu tekan pintasan keyboard yang Anda cari dan keluar. Bagi saya Ctrl+Bmenghasilkan di \002mana saya berhasil terikat pada perintah

bind '"\002":"echo command"'

Selain itu, jika Anda ingin perintah dieksekusi segera (tidak hanya dimasukkan ke dalam prompt), Anda dapat menambahkan Enter ke akhir perintah Anda, seperti:

bind '"\002":"echo command\015"'

Peter Perháč
sumber