Trong bash, làm cách nào để liên kết một phím chức năng với một lệnh?


91

Ví dụ: Tôi muốn liên kết F12khóa với lệnh echo "foobar"để mỗi khi tôi nhấn F12, thông báo "foobar" sẽ được in ra màn hình. Lý tưởng nhất là nó có thể là bất kỳ lệnh shell tùy ý nào, không chỉ là nội trang. Làm thế nào để một người đi về điều này?

Câu trả lời:


163

Bạn có thể xác định chuỗi ký tự được tạo ra bởi một phím bằng cách nhấn Ctrl- vtại dòng lệnh, sau đó nhấn phím bạn quan tâm. Trên hệ thống của tôi F12, tôi nhận được ^[[24~. Các ^[đại diện Esc. Các loại thiết bị đầu cuối hoặc trình giả lập đầu cuối khác nhau có thể phát ra các mã khác nhau cho cùng một khóa.

Tại dấu nhắc Bash, bạn có thể nhập một lệnh như thế này để bật macro khóa để bạn có thể dùng thử.

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

Bây giờ, khi bạn nhấn F12, bạn sẽ nhận được "foobar" trên dòng lệnh sẵn sàng để chỉnh sửa thêm. Nếu bạn muốn gõ phím để nhập lệnh ngay lập tức, bạn có thể thêm một dòng mới:

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

Bây giờ khi bạn nhấn F12, bạn sẽ thấy thư mục hiện tại được hiển thị mà không cần phải nhấn Enter. Điều gì sẽ xảy ra nếu bạn đã nhập một cái gì đó trên dòng và bạn sử dụng nó để tự động thực thi? Nó có thể trở nên lộn xộn. Tuy nhiên, bạn có thể xóa dòng như một phần của macro của mình:

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

Khoảng trống đảm bảo rằng dấu Ctrl- ucó thứ gì đó cần xóa để giữ cho chuông không kêu.

Khi bạn đã có macro hoạt động theo cách bạn muốn, bạn có thể làm cho nó hoạt động bền bỉ bằng cách thêm nó vào ~/.inputrctệp của bạn . Không cần bindlệnh hoặc tập hợp các dấu ngoặc kép bên ngoài:

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

Biên tập:

Bạn cũng có thể tạo một ràng buộc khóa để thực thi một cái gì đó mà không làm ảnh hưởng đến dòng lệnh hiện tại.

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

Sau đó, trong khi bạn đang nhập một lệnh yêu cầu tên người dùng, chẳng hạn và bạn cần biết tên của người dùng đã đăng nhập, bạn có thể nhấn Alt- Shift- Wvà kết quả củawho sẽ được hiển thị và lời nhắc sẽ được cấp lại giữ nguyên lệnh một phần của bạn và con trỏ ở cùng vị trí trong dòng.

Thật không may, điều này không hoạt động đúng đối với các phím chẳng hạn như F12xuất ra nhiều hơn hai ký tự. Trong một số trường hợp, điều này có thể được giải quyết.

Lệnh ( whotrong trường hợp này) có thể là bất kỳ thực thi nào - một chương trình, tập lệnh hoặc hàm.


2
Điều gì sẽ xảy ra nếu tôi muốn thêm ràng buộc vào "ctrl + q"?
kubudi

5
@kubudi: bind '"\C-q": menu-complete'ví dụ (hoặc trong của bạn ~/.inputrc: "\C-q": menu-complete). Bạn cũng có thể cần stty -ixontrong của bạn ~/.bashrcđể kiểm soát dòng chảy vô hiệu hóa và làm ^ S và ^ Q sẵn.
Tạm dừng cho đến khi có thông báo mới.

Bạn nói điều đó ^[đại diện escvà sau đó bạn dường như thay thế nó \etrong ví dụ của mình. Bạn có thể giải thích tại sao không?
Remover

1
@Remover: Là ^[biểu diễn đầu ra. Đây \elà một cách để nhập nó ( ^[không hoạt động cho điều đó).
Tạm dừng cho đến khi có thông báo mới.

Làm cách nào để liên kết "\ Cz"? Tôi muốn nhận được một cái gì đó giống như những gì được mô tả cho zsh trên sheerun.net/2014/03/21/how-to-boost-your-vim-productivity
pkoch

19

Bạn có thể xác định các ràng buộc khóa bash trong ~/.inputrc (tệp cấu hình cho thư viện GNU Readline). Cú pháp là

<keyym hoặc key name>: macro

ví dụ:

Control-o: "> output"

sẽ tạo macro chèn "> output" khi bạn nhấn ControlO

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

sẽ tạo một macro chèn "echo foobar" khi bạn nhấn F1... Tôi không biết từ viết tắt của nó là gìF11 tắt của nó là gì.

Biên tập:

.inputrchiểu \ntrình tự thoát cho dòng cấp dữ liệu, vì vậy bạn có thể sử dụng

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

Điều này sẽ hiệu quả 'nhấn enter' sau khi lệnh được đưa ra.


4
bạn có thể sử dụng "\ n" trong macro, để thêm ký tự dòng mới:
Barton Chittenden

Điều này hoạt động tốt hơn đối với tôi vì nó xác định ánh xạ khóa khi mở một thiết bị đầu cuối.
Heldraug

Đối với Alt, sử dụng \e, ví dụ "\eo": "> output".
Jānis Elmeris

Đối với một sâu hơn hướng dẫn về sử dụng .inputrcsee hackaday.com/2018/01/19/linux-fu-custom-bash-command-completion
Josh Habdas

1
@ArthurHenriqueDellaFraga Tôi đã chỉnh sửa câu trả lời; nó sẽ nằm trong thư mục chính của bạn. Nếu nó không tồn tại, bạn có thể tạo nó.
Barton Chittenden

7

Giải pháp này dành riêng cho môi trường X11 và không liên quan gì đến bash, nhưng thêm phần sau vào .Xmodmaps của bạn

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

sẽ gửi chuỗi "foobar" đến thiết bị đầu cuối khi nhấn F12.


Hãy nhớ rằng điều này không giống như trình bao chạy một lệnh. Nếu bạn thực sự muốn chạy một lệnh, bạn sẽ phải nhấn enter (hoặc yêu cầu chuỗi được gửi làm điều đó cho bạn). Chắc cũng muốn an toàn nên dọn đường trước.
Cascabel

2
Điều này sẽ thật tuyệt vời, nhưng nó dường như không hoạt động như Fedora 20. Tôi thậm chí đã thử sử dụng xev để tìm mã khóa thích hợp cho F12 trước (trong trường hợp của tôi là 96) và sử dụng nó thay vì 88. Cả hai đều không hoạt động.
BobDoolittle

2

Tôi muốn liên kết Ctrl+Bvới một lệnh. Lấy cảm hứng từ một câu trả lời ở trên, tôi đã cố gắng sử dụng bindnhưng không thể tìm ra chuỗi câu trả lời khó hiểu ( \e[24~?) Dịch sangCtrl+B .

Trên máy Mac, đi tới Cài đặt của ứng dụng Terminal, Cấu hình -> Bàn phím -> +sau đó nhấn phím tắt bạn đang theo dõi và nó sẽ xuất hiện. Đối với tôi, Ctrl+Bkết quả là \002tôi đã liên kết thành công lệnh

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

Ngoài ra, nếu bạn muốn lệnh được thực thi ngay lập tức (không chỉ được chèn vào dấu nhắc), bạn có thể thêm Enter vào cuối lệnh của mình, như sau:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.