Có một phím tắt để thực hiện một loạt các lệnh trong lịch sử bash không?


20

Giả sử tôi có ví dụ tầm thường sau đây trong history:

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

Nếu tôi muốn thực hiện các lệnh 77, 7879trong một lệnh, không có tồn tại một phím tắt cho việc này? Tôi đã thử !77 !78 !79, đơn giản là sẽ đặt tất cả chúng trên một dòng để thực thi.


9
Được !77 ; !78 ; !79không
thrig

1
Tôi đoán bất cứ điều gì ngắn gọn khi gõ từng dòng là ok, nhưng hy vọng điều gì đó ngắn gọn hơn một chút (dọc theo dòng !77-79)
MrDuk

1
@MrDuk, cậu bé đã làm tôi mất một lúc để nhớ. Xem câu trả lời cập nhật của tôi cho giải pháp rất súc tích ! :)
tự đại diện

Thật kỳ diệu! :)
MrDuk

Câu trả lời:


28

EDIT: Bạn có thể thực hiện việc này theo cách tương thích POSIX với công cụ lệnh sửa lỗifc :

fc 77 79

Điều này sẽ mở trình soạn thảo của bạn (có thể vi) với các lệnh 77 đến 79 trong bộ đệm. Khi bạn lưu và thoát ( :x), các lệnh sẽ được chạy.


Nếu bạn không muốn chỉnh sửa chúng và bạn RẤT RẤT NHIỀU bạn biết bạn đang gọi lệnh nào, bạn có thể sử dụng:

fc -e true 77 79

Cái này sử dụng truenhư một "trình soạn thảo" để chỉnh sửa các lệnh, vì vậy nó chỉ thoát mà không thực hiện bất kỳ thay đổi nào và các lệnh được chạy như hiện trạng.


TRẢ LỜI GỐC:

Bạn có thể dùng:

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

Điều này giả định rằng bạn không sử dụng bất kỳ bí danh hoặc hàm hoặc bất kỳ biến nào chỉ có trong môi trường thực thi hiện tại, vì tất nhiên những cái đó sẽ không có sẵn trong shell mới được bắt đầu.


Một giải pháp tốt hơn (cảm ơn Michael Hoffman đã nhắc nhở tôi trong các bình luận) là:

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

Một trong những trường hợp rất, rất ít evalthực sự phù hợp!


Cũng thấy:


2
Điều này sẽ không hoạt động chính xác nếu bất kỳ lệnh nào thay đổi môi trường thực thi hiện tại, ví dụ, bằng cách thay đổi một biến hoặc thực hiện cd, nhưng đó là trường hợp cạnh.
G-Man nói 'Phục hồi Monica'

3
eval "$(history -p \!{77..79})"nên làm việc.
Michael Hoffman

1
@MichaelHoffman, tôi đã nghĩ về điều đó và nghĩ rằng tôi đã thử nó, nhưng tôi chỉ nhận ra rằng tôi đã bỏ qua trích dẫn! Ôi! Không có gì ngạc nhiên khi nó không hoạt động ... chỉnh sửa câu trả lời ngay bây giờ.
tự đại diện

14

Câu trả lời đơn giản: thay vì !77 !78 !79,

  • !77; !78; !79để làm những gì bạn dường như đang cố gắng thực hiện - thực hiện lệnh 77, rồi lệnh 78, rồi lệnh 79, vô điều kiện, hoặc
  • !77 && !78 && !79 để thực thi lệnh 77 và kiểm tra xem nó đã thành công chưa. Và sau đó, nếu lệnh 77 thành công, thực thi lệnh 78. Và sau đó, nếu lệnh 78 thành công, thực thi lệnh 79.

Câu trả lời hơi thông minh hơn (nếu bạn đang ở trong cửa sổ kiểu thiết bị đầu cuối):

  • Chỉ ra số lệnh nào mà lệnh tiếp theo bạn nhập sẽ là.
    • Có thể bao gồm điều này trong lời nhắc của bạn; Tôi tin rằng nó bằng cách bao gồm \!trong của bạn PS1.
    • Hoặc nhìn vào danh sách lịch sử của bạn. Nếu mục cuối cùng là 82 history, thì lệnh tiếp theo của bạn là 83.
  • Trừ 83−77 = 6.
  • Loại !-6. Điều này sẽ thực hiện lại lệnh 77.
  • Chọn !-6, sao chép và dán nó. Vì việc thực hiện lại lệnh 77 ( ./generator.sh) của bạn là lệnh 83, nên bây giờ bạn đang ở lệnh 84, do đó !-6sẽ thực hiện lại lệnh 78.
  • Lặp lại dán !-6như mong muốn.
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.