Làm thế nào để thực hiện các lệnh liên tiếp từ lịch sử?


49

Giả sử tôi muốn thực hiện một chuỗi bốn lệnh mà tôi đã thực hiện trước đó. Nếu cái đầu tiên là 432 trong lịch sử chỉ huy, thì tôi có thể làm:

$ !432; !433; !434; !435

Tôi tò mò, có cách nào hiệu quả hơn để thực hiện điều này không?


1
Không đăng bài này dưới dạng câu trả lời vì nó không thực thi các lệnh, nhưng bạn có thể gõ history -p \!43{2..5}để in các lệnh 432 đến 435 đến thiết bị đầu cuối, phù hợp cho việc sao chép / dán tiếp theo.
tự đại diện

Câu trả lời:


48

Nếu nó đề cập đến các lệnh vừa mới chạy, một cách hiệu quả hơn là tham chiếu chúng với các số âm:

!-4; !-3; !-2; !-1

Ngoài ra, một khi bạn làm điều đó, mục lịch sử cuối cùng của bạn sẽ chứa toàn bộ chuỗi lệnh, vì vậy bạn có thể lặp lại nó với !!.


Chỉnh sửa: Nếu bạn chưa có, hãy làm quen với chức năng dựng sẵn tuyệt vời fc, được đề cập bởi Gilles . (Sử dụng help fc.) Hóa ra bạn cũng có thể sử dụng số âm với nó, vì vậy bạn có thể làm tương tự như trên bằng cách sử dụng

eval "`fc -ln -4 -1`"

Điều này có một cảnh báo, mặc dù: sau này, evaldòng được lưu trữ trong lịch sử như là lệnh cuối cùng. Vì vậy, nếu bạn chạy lại cái này, bạn sẽ rơi vào một vòng lặp!

Một cách an toàn hơn để làm điều này là sử dụng fcchế độ hoạt động mặc định : chuyển tiếp phạm vi lệnh đã chọn đến một trình soạn thảo và chạy chúng sau khi bạn thoát khỏi nó. Thử:

 fc -4 -1

Bạn thậm chí có thể đảo ngược thứ tự của phạm vi lệnh: fc -1 -4


Tôi chỉ đọc những gì tôi đã viết ... LOL. Trên thực tế, tôi không chắc chắn về việc khôi phục ( có thể gọi lại có thể không?), Nhưng cảm ơn vì đã nói :) Tôi luôn đánh giá cao sự điều chỉnh.
rozcietrzewiacz

Scrabblefinder.com nói rebvoke là một từ Scrabble hợp lệ. Không thể có được bất kỳ dứt khoát hơn thế. :)
BentFX

1
Với một câu trả lời hay như thế này (+1), không quan trọng bạn đánh vần nó như thế nào; đặc biệt là không phải dạng chính tả nào xuất hiện trong 3 từ điển tiếng Anh chính : Oxford, Camgridge, Merriam-Webster (Tôi sẽ dùng dấu gạch nối)
Peter.O

34

Để xem một loạt các lệnh trong lịch sử, hãy sử dụng fclệnh tích hợp:

fc -ln 432 435

Để thực hiện lại chúng:

eval "$(fc -ln 432 435)"

4
Rất đẹp. Mặc dù tôi tò mò, tại sao man fckhông cho tôi bất cứ điều gì. Không đại diện fccho cái gì? tùy chọn khác là gì ở đó?
Eric Wilson

2
@Eric Wilson ... gõ help fc... và cả help help.... help: help [-dms] [mẫu ...] Hiển thị thông tin về các lệnh dựng sẵn.
Peter.O

Tôi vừa trở lại đây, tìm kiếm câu trả lời của bạn. Đây thực sự là một nội dung tuyệt vời! Đặc biệt khi bạn là chức năng mặc định của nó - gọi trình soạn thảo để sửa đổi một loạt các lệnh sẽ được phát lại. Cảm ơn, Gilles.
rozcietrzewiacz

1
Không có -lcờ, nó sẽ thực thi mà không cần đến tà ác eval.
Bernhard

1
@EricWilson Một tìm kiếm google dẫn tôi đến cuốn sách "Unix in a Nutshell" có fcnghĩa là "lệnh tìm" hoặc "lệnh sửa".
Slothworks

10

Có một cách hay và thay thế để chạy một số lệnh theo trình tự từ lịch sử Bash:
thay vì sử dụng thay thế lịch sử ( !432hoặc !-4), bạn có thể tìm kiếm trong lịch sử bằng Ctrl+ rvà khi bạn đã tìm thấy lệnh đầu tiên bạn muốn chạy, nhấn Ctrl+ o(thao tác và nhận-tiếp theo ) thay vì returnphím
Điều này sẽ khởi chạy lệnh và đề xuất lệnh tiếp theo từ lịch sử. Bạn có thể nhấn Ctrl+obao nhiêu lần tùy ý và kết thúc chuỗi bằng returnmột lần cuối hoặc Ctrl+cdừng lại mà không khởi chạy nó.


Hmm, sau khi tôi nhấn Ctrl-onó chỉ xuất ra một chữ ^ovà phá vỡ của tôi (reverse-i-search). Có lẽ có một số thiết lập khác liên quan.
Ciro Santilli 心 心 事件

8

Để thực hiện các lệnh ngay lập tức thay vì chỉnh sửa chúng, đây là phiên bản trả lời của Giles mỏng hơn về mặt cú pháp bằng cách sử dụng eval :

fc -e: 432 435

Đối số dấu hai chấm cho -e là bash noop, có tác dụng bỏ qua bước "mở trong trình chỉnh sửa" mà fc muốn. Ngoài ra, bây giờ lịch sử (gần đây) sẽ chứa các lệnh thực tế từ lịch sử, thay vì tuyên bố eval.


0

fc cho vòng lặp và xsel

Điều này hoạt động tốt khi tôi muốn nối và chạy lại các lệnh n cuối cùng nhiều lần:

fcn() (
  from="${1:-2}"
  to="${2:-1}"
  if [ "$from" -ne "$to" ]; then
    for i in `seq "$from" -1 "$(($to + 1))"`; do
      printf "$(fc -ln -${i} -${i}) && "
    done
  fi
  printf "$(fc -ln -${to} -${to})"
)

Sau đó:

$ echo a
a
$ echo b
b
$ echo c
c
$ fcn 3 1 | xsel -b
$ # Paste.
$  echo a &&  echo b &&  echo c
a
b
c
$ # Paste again if you feel like it.
$  echo a &&  echo b &&  echo c
a
b
c

Hoặc đối với các lệnh lớn hơn có thể cần chỉnh sửa:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
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.