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?
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?
Câu trả lời:
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, eval
dò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 fc
chế độ 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
Để xem một loạt các lệnh trong lịch sử, hãy sử dụng fc
lệnh tích hợp:
fc -ln 432 435
Để thực hiện lại chúng:
eval "$(fc -ln 432 435)"
man fc
không cho tôi bất cứ điều gì. Không đại diện fc
cho cái gì? tùy chọn khác là 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.
-l
cờ, nó sẽ thực thi mà không cần đến tà ác eval
.
fc
nghĩa là "lệnh tìm" hoặc "lệnh sửa".
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ử ( !432
hoặ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ó.
Ctrl-o
nó chỉ xuất ra một chữ ^o
và phá vỡ của tôi (reverse-i-search)
. Có lẽ có một số thiết lập khác liên quan.
Để 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.
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
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.