it-swarm-vi.tech

Làm thế nào tôi có thể tìm kiếm lịch sử bash và chạy lại một lệnh?

Tôi có thể tìm kiếm lịch sử trong bash và chạy kết quả không?

292
Richard Hoskins

Kiểu CtrlR tại dòng lệnh và bắt đầu gõ lệnh trước đó. Khi kết quả xuất hiện, hãy tiếp tục nhấn CtrlR để xem các trận đấu khác. Khi lệnh bạn muốn xuất hiện, chỉ cần nhấn Enter

Lưu ý rằng trong khi CtrlR là mặc định, nếu bạn muốn lệnh (reverse-search-history) bị ràng buộc với CtrlT bạn có thể cấu hình nó với các mục sau:

[.__.] liên kết '"\ C-t": lịch sử tìm kiếm ngược' [.__.]

Có cả một loạt các lệnh ràng buộc đọc khác cũng có sẵn cho bạn. Hãy xem trang người dùng bashNAME_ .

Bash có nhiều phương tiện để tìm kiếm và truy cập lịch sử lệnh tương tác. Cơ bản nhất trong số đó là nội dung historyname__. Gõ chỉ:

[.__.] $ history [.__.]

Sẽ in một danh sách các lệnh cùng với một chỉ mục số, như:

[.__.] $ history [.__.] 1 xóa [.__.] 2 ls -al [.__.] 3 vim ~/somefile.txt [.__.] 4 history [.__.] $ 

Sau đó, bạn có thể thực thi bất kỳ lệnh nào trong số này bằng cách sử dụng chỉ mục số của chúng bằng cách đặt trước chỉ mục bằng một !, như Mitch chỉ ra:

[.__.] $! 1 [.__.]

Sẽ thực thi lệnh clearname__. Bản dựng lịch sử có nhiều tính năng, bạn có thể xem thêm trong các trang man bashhistoryname__.

Bạn cũng có thể chỉ định các độ lệch âm tương đối khi sử dụng chỉ định !, vì vậy sử dụng danh sách lịch sử của chúng tôi ở trên, nếu chúng tôi muốn thực hiện lại vimname__, chúng tôi có thể làm:

[.__.] $! -2 [.__.]

Về cơ bản là bảo bash thực thi lệnh bạn đã chạy "hai lệnh trước". Để chạy lệnh trước đó trong danh sách lịch sử, chúng ta chỉ cần sử dụng !! (chỉ là viết tắt cho !-1).

Trình chỉ định ! không giới hạn bạn chỉ định số lượng lệnh nào sẽ chạy. hayalci cho thấy rằng bạn có thể hướng dẫn bashthực thi một lệnh dựa trên văn bản mà nó bắt đầu bằng (sử dụng !) hoặc văn bản trong chính lệnh đó (sử dụng !?). Một lần nữa, sử dụng danh sách lịch sử ví dụ của chúng tôi ở trên, nếu chúng tôi muốn thực hiện lại clearname__, tất cả những gì chúng tôi cần làm là gõ:

[.__.] $! cl [.__.]

và hãy nhấn Enter. Và còn vimthì sao? Điều đó đơn giản như:

[.__.] $ !? Một số [.__.]

Điểm quan trọng nhất từ ​​phản hồi của hayalci là cuộc gọi đến nội dung shoptname__:

[.__.] $ shopt -s histverify [.__.]

Điều này sẽ cho phép xác minh lịch sử để các lệnh được khớp bởi các chỉ định !, !!!? không được thực thi một cách mù quáng, mà thay vào đó được điền vào dòng lệnh để bạn có thể đảm bảo chúng sẽ không làm điều ác trước khi thực hiện chúng. Điều này thậm chí còn quan trọng hơn khi bạn đang thực thi các lệnh với tư cách là người dùng root. Tùy chọn này có thể được đặt trong tệp khởi động .bashrc của bạn để nó được đặt bất cứ khi nào bạn đăng nhập.

Như đã được chỉ ra, tất cả các thông tin này có thể được lượm lặt từ trang man bashNAME_ . Dành cho !, !!, và!? người chỉ định, hãy xem Phần Mở rộng Lịch sử 9. .

421
Sean Bright

Thay thế cho crtl+R, bạn có thể tìm kiếm lịch sử bằng cách gõ

!text

Điều này sẽ tìm kiếm lịch sử cho lệnh gần đây nhất bắt đầu với 'văn bản'.

Nhưng tôi khuyên bạn nên đặt cái này trong .bashrc để ngăn thực thi lệnh sai.

shopt -s histverify

Điều này hướng dẫn bash sao cho, sau bất kỳ hành động lịch sử (như !!:s/prev_text/after_text), nó đặt dòng kết quả vào lệnh Nhắc. Sau đó, bạn có thể xem lại hoặc chỉnh sửa lệnh và nhấn Enter sau đó.

36
hayalci

Bạn cũng có thể làm:

history | grep "stuff"

nó sẽ trả lại một cái gì đó như

num stuff

sau đó bạn có thể gõ

!num
30
Mitch

Tôi thích sử dụng lịch sử tìm kiếm-lạc hậu hơn lịch sử tìm kiếm ngược. Cái trước cho phép bạn gõ một vài ký tự của lệnh sau đó nhấn phím tìm kiếm, trái với việc nhấn phím tìm kiếm trước sau đó nhập chuỗi tìm kiếm.

Theo mặc định trên hệ thống của tôi, M-p và M-n liên kết với các chức năng tương tự nhưng tôi thích ràng buộc các phím mũi tên hơn:

bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
14
Keith

Tôi có một bí danh thực sự tuyệt vời, h. Nó thực sự chỉ là "history | grep", nhưng tôi lọc ra các mục "lệnh h" trước đó bằng "grep -E -v"

alias h="history | grep -E -v '^ *[0-9]+ *h ' | grep "

được sử dụng như

h aliases
2003  less .bash_aliases
13
CurtH

Tuyệt vời, Sean! Tôi sẽ đưa điều này vào một bình luận, nhưng tôi có một vài điểm danh tiếng ngại ngùng. :-)

Một kỹ thuật hữu ích và liên quan khác là khả năng chạy lệnh trước đó trong khi thay đổi Word. Giả sử bạn đánh máy tên thư mục hoặc muốn thay đổi tên tệp:

$ echo tên tôi là bob [.__.] tên tôi là bob [.__.] $ ^ bob ^ jordan [.__.] echo tên tôi là jordan

Lưu ý rằng lệnh được mở rộng, thay thế và xuất ra trước khi lệnh được chạy, vì vậy nếu lệnh sai được chạy, bạn có thể thấy bash nghĩ nó đang làm gì.

12
Jordan

Vì điều hướng trong lịch sử bằng Ctrl-r là cồng kềnh, bạn có thể muốn xem xét hh :

https://github.com/dvorka/hstr

giúp điều hướng đơn giản hơn, đơn giản và hiệu quả hơn - bao gồm chạy lệnh:

enter image description here

5
Martin Dvorak

Tại lệnh bash Prompt, gõ control-R, sau đó nhập một vài ký tự của lệnh bạn muốn và cơ sở đọc dòng của bash sẽ tìm kiếm trong lịch sử lệnh cho lệnh đó.

Sau khi bạn đã bắt đầu tìm kiếm, bạn có thể nhập lại control-R để chuyển sang lệnh khớp tiếp theo.

3
John1024

Nếu bạn đã cấu hình Shell của mình để sử dụng các ràng buộc khóa vi (set -o vi hoặc có set editing-mode vi trong $HOME/.inputrc), thì bạn tìm kiếm bằng <Esc>/some-command<Return> và nhấn n (tiếp theo) hoặc Shift-n (trước đó).

3
Fernando Basso

CTRL+R hoạt động tốt, như @ John1024 đã đề xuất, nhưng hơi tẻ nhạt nếu nhiều lệnh gần đây của bạn tương tự và bạn muốn một cách nhanh chóng để quét tất cả chúng. Một cách khác là sử dụng historyNAME _ :

$ history | grep keyword
2
Mureinik

Tôi thích HSTR nhưng đôi khi dường như tôi không thể cài đặt nó. Vì vậy, tôi đã viết một bí danh bằng cách sử dụng fzf để bắt chước hành vi của nó (hx, cho "lịch sử thực hiện")

alias hx='eval $(history | sed "s/^ *[0-9]* *//g" | fzf --tac --tiebreak=index --height=10)'
  • history: tốt, lấy lịch sử
  • sed: xóa cột số khỏi danh sách (POSIX)
  • fzf: đây là phép thuật, cho phép bạn tìm kiếm danh sách mờ một cách tương tác hoặc di chuyển với C-JC-K, sau đó thực hiện lệnh bằng Enter.
  • --height: đặt số lượng dòng được hiển thị.
  • --tac: danh sách hoàn nguyên (logic hơn cho lịch sử)
  • --tiebreak=index: giữ thứ tự lịch sử khi fzf cập nhật kết quả
0
Biggybi