Phím tắt lịch sử Bash cho! *


8

Trong Bash, có một số toán tử tiện dụng để lặp lại các phần của lệnh cuối cùng:

  • !^ mở rộng đến đối số đầu tiên của lệnh trước đó, vd

    $ echo one "two three"
    one two three
    $ echo !^
    echo one
    one
    
  • !$ mở rộng đến đối số cuối cùng của lệnh trước đó, vd

    $ echo one "two three"
    one two three
    $ echo !$
    echo "two three"
    two three
    
  • !* mở rộng cho tất cả các đối số của lệnh trước đó, vd

    $ echo one "two three"
    one two three
    $ echo !*
    echo one "two three"
    one two three
    

(Theo như tôi hiểu, đây là cú pháp đường cho !!:^, !!:$!!:*tương ứng, nơi !!là một vấn thiết kế trường hợp mở rộng để các lệnh trước, và ^, $*là định danh từ, xem Bash Reference Manual hoặc man bash.)

Đây thường là khá tiện dụng. Nhưng nó thậm chí còn mát hơn với các phím tắt:

  • Khi bạn nhấn Alt+ .hoặc Alt+ _, đối số cuối cùng của lệnh trước được chèn vào lệnh hiện tại, tương tự như khi bạn đã viết !$tại điểm đó.

  • Cũng có thể nhấn Alt+ Ctrl+ yđể chèn đối số đầu tiên của lệnh trước đó, như thể bạn đã viết !^tại thời điểm đó.

(Xem Thư viện Đọc GNU hoặc info readline.)

Tôi có xu hướng thích các phím tắt trên các toán tử lịch sử của Bash, bởi vì tôi có thể thấy những gì tôi đang chèn trước khi tôi thực sự thực hiện lệnh. Tuy nhiên, dường như không có một phím tắt nào cho phép tôi chèn tất cả các từ của lệnh trước đó, tức là một công việc không phải !*là công việc. Ít nhất là tôi không thể tìm thấy nó.

Có một lối tắt như vậy? Nếu không, có thể cấu hình thư viện readline để thêm một, và làm thế nào?


AFAIK, các phím tắt được xử lý bởi trình giả lập thiết bị đầu cuối. Vì vậy, tôi cho rằng bạn đang sử dụng gnome-terminal?
Seth

1
Trong zsh, nếu bạn gõ echo !*và sau đó nhấn TAB, bạn có hiệu ứng mong muốn. Nói chung, TAB trong khi đọc sẽ mở rộng tất cả các mở rộng. Rất tiện dụng; Có lẽ bash sẽ có một số cấu hình để có hiệu lực tương tự? @ Vì vậy, tôi nghĩ rằng đây là dòng đọc thành bash, không phải trình giả lập thiết bị đầu cuối - mặc dù không chắc chắn.
Rmano

2
@ Không, các phím tắt từ Q được xử lý bằng bash. Bạn có thể serch cho 'lệnh cho Thao tác với Lịch sử' trong man bash(ở đâu đó tại dòng 3030)
Radu Rădeanu

@ RaduRădeanu Ôi thật thú vị! Tôi không biết điều đó. Xấu của tôi cho những giả định xấu
Seth

1
\e.\e_được ánh xạ tới chức năng đọc yank-last-arg\e\C-yđược ánh xạ tới yank-nth-arg. Đáng buồn thay, dường như không có lệnh (đơn) nào thêm nhiều đối số trước đó cùng một lúc.
Adaephon

Câu trả lời:


5

Nếu bạn nhìn vào đầu ra của lệnh sau:

bind -l

hoặc tốt hơn để:

bind -l | grep arg

bạn có thể thấy rằng không tồn tại bất kỳ chức năng đọc nào cho tất cả các đối số như, ví dụ, yank-last-argđối với đối số cuối cùng - có thể chèn đối số cuối cùng vào lệnh trước đó (từ cuối cùng của mục lịch sử trước đó). Vì vậy, nếu một chức năng như vậy không tồn tại, rất có thể không tồn tại một lối tắt để thực hiện những gì bạn muốn.

Chúng ta hãy cố gắng đưa ra một yêu cầu tiếp cận với yêu cầu của bạn ...

Đầu tiên, hãy xem ví dụ ở đầu ra của lệnh sau:

bind -p | grep yank-nth-arg

Đầu ra là:

"\e\C-y": yank-nth-arg

và có thể được dịch như sau: yank-nth-arg(chèn đối số đầu tiên vào lệnh trước - với đối số n, chèn đối số thứ n từ lệnh trước) được liên kết với Alt+ Ctrl+ y.

Theo cách tương tự có thể được giải thích bất kỳ dòng nào từ đầu ra của bind -plệnh.

Bây giờ chơi chú ý ở các tình huống sau:

  • Nếu bạn đặt ràng buộc sau:

    bind '"\ea": "\e2\e."'

    Alt+ Asẽ được ánh xạ tới Alt+ 2Alt+ .được ánh xạ để chèn đối số thứ hai của lệnh trước đó. Vì vậy, sau khi bạn nhấn Alt+ A, đối số thứ hai của lệnh trước được chèn vào lệnh hiện tại.

  • Nếu bạn đặt:

    bind '"\ea": "\e1\e. \e2\e."'

    Sau khi bạn nhấn Alt+ A, hai đối số đầu tiên của lệnh trước được chèn vào lệnh hiện tại. Nếu số lượng đối số từ lệnh trước tối đa là 2, tất nhiên tất cả các lệnh trước đó được chèn vào lệnh hiện tại.

  • Nếu bạn đặt:

    bind '"\ea": "\e1\e. \e2\e. \e3\e."'

    Sau khi bạn nhấn Alt+ A, ba đối số đầu tiên của lệnh trước được chèn vào lệnh hiện tại. Nếu số lượng đối số từ lệnh trước tối đa là 3 (như trong trường hợp của bạn), tất nhiên tất cả các lệnh trước đó được chèn vào lệnh hiện tại.

  • Và như thế.

Đối với 10 đối số đầu tiên, bạn có thể sử dụng:

bind '"\ea": "\e1\e. \e2\e. \e3\e. \e4\e. \e5\e. \e6\e. \e7\e. \e8\e. \e9\e. \e1\e0\e."'

Và tôi nghĩ rằng điều này đủ dài khi tôi không sử dụng các lệnh quá thường xuyên với quá nhiều đối số.

Để làm cho nó liên tục, hãy thêm dòng dòng sau vào ~/.inputrctệp của bạn :

"\ea": "\e1\e. \e2\e. \e3\e. \e4\e. \e5\e. \e6\e. \e7\e. \e8\e. \e9\e. \e1\e0\e."

Trong ví dụ này tôi đã chọn Alt+ Ađể chèn tất cả các đối số (nếu số lượng đối số không lớn hơn 10) của lệnh trước đó, nhưng bạn có thể chọn bất kỳ kết hợp nào khác với bạn bằng cách thay thế trong lệnh trước đó \eachuỗi.

Tài nguyên:


Chà, nó hơi hack, và nó sẽ chỉ hoạt động với một số lượng đối số hạn chế, nhưng nó dường như là thứ gần nhất mà chúng ta có thể dễ dàng nhận được - Tôi sẽ xem nó;) Thật ra tôi chỉ xem mã nguồn của readline. Thoạt nhìn có vẻ như trong tệp funmap.c, hàm yank-nth-argđược ánh xạ tới hàm C rl_yank_nth_arg, lần lượt được định nghĩa trong kill.c. Tương tự cho yank-last-arg. Tất nhiên có thể mở rộng đường đọc với chức năng như vậy, nhưng tôi không muốn làm điều đó; Tôi thích readline tôi được quản lý bởi apt, và tính năng này không quan trọng;)
Malte Skoruppa
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.