Có cách nào để thực hiện các lệnh từ lịch sử?


99

Ví dụ:

[root@ip-10-0-7-125 ~]# history | grep free
  594  free -m
  634  free -m | xargs | awk '{print "free/total memory" $17 " / " $ 8}'
  635  free -m
  636  free -m | xargs | awk '{print "free/total memory" $9 " / " $ 10}'
  736  df -h | xargs |  awk '{print "free/total disk: " $11 " / " $9}'
  740  df -h | xargs |  awk '{print "free/total disk: " $11 " / " $8}'
  741  free -m | xargs | awk '{print "free/total memory: " $17 " / " $8 " MB"}'

Tôi chỉ tự hỏi liệu có cách nào để thực thi lệnh 636 mà không cần gõ lại không, chỉ cần gõ một cái gì đó cộng với số, như lịch sử 636 hoặc một cái gì đó.


14
Bạn biết đến ctrl-r?
Carlos Campderrós

1
Đúng, tôi biết điều đó nhưng nó không chính xác như những gì tôi muốn.
Một

Câu trả lời:


170

Trong bash, chỉ cần !636sẽ ổn thôi.


12
In Linux- Điều này có liên quan nhiều hơn đến trình bao (bash, zsh, v.v.) một người đang chạy thì hệ điều hành bạn đang chạy. Có shell trên linux mà không hỗ trợ cho lịch sử.
Zoredache

@Zoredache Và tương tự, điều này hoạt động tốt trong hầu hết các triển khai bash trên Windows.
Ajedi32

1
Tất nhiên, không chỉ bash, mà cả các shell khác nữa - bao gồm cả csh.
vẽ

5
Nếu bạn có một lệnh rất giống với những gì bạn muốn chạy, bạn có thể nối thêm :pđể in lệnh mà không chạy nó, !636:pví dụ. Điều đó có nghĩa là bạn có thể dễ dàng chọn lại từ lịch sử của mình bằng cách nhấn mũi tên lên và thực hiện các thay đổi nhỏ bạn muốn
AJefferiss

78

Vâng, nó được gọi là "mở rộng lịch sử." Xem

LESS='+/^HISTORY EXPANSION' man bash

để biết chi tiết đầy đủ.

Sử dụng một dấu chấm than theo sau là một số được cho là cách sử dụng đơn giản nhất:

!636

Tuy nhiên, bạn cũng có thể chạy lệnh thực thi cuối cùng trực tiếp mà không cần biết số lịch sử của nó:

!!

Hoặc bạn có thể chạy hai lệnh trở lại:

!-2

Tuy nhiên, hình thức tôi thường sử dụng nhất là lặp lại đối số cuối cùng của lệnh cuối cùng:

echo this text goes into a file > /tmp/afile.txt
cat !$

Hoặc giả sử tôi đang kiểm tra một tập tin. Sử dụng hoàn thành tab, tôi có thể làm như sau:

ls -l /really/long/path/to/some/file
less !$

Một lần nữa, đọc trang người đàn ông để biết thêm chi tiết:

LESS='+/^HISTORY EXPANSION' man bash

25
Tương tác, Alt-.có thể thuận tiện hơn !$. Nó chèn đối số cuối cùng của lệnh cuối cùng nguyên văn vào dòng.
ulidtko

2
@ulidtko Những lối thoát đặc biệt đó được ghi lại ở đâu (tôi biết !$, nhưng chưa bao giờ nghe về Alt-.)? Bạn sẽ gửi một liên kết đến nó, xin vui lòng?
edmz

5
LESS="+/DEFAULT KEY BINDINGS" man 3 readline, /etc/inputrc, ~/.inputrc. Nhiều chương trình ngoài bash sử dụng libreadline; đối với những người làm, bạn sẽ có được các tính năng tương tự như Alt-., Ctrl-X-U(hoàn tác), Ctrl-/(mô tả phím tắt), hoàn thành tab, v.v. - miễn phí. Ví dụ, chỉ với ba dòng của PYTHONSTARTUPmột người có thể kích hoạt hoàn thành tab và lịch sử trong REPL python stock . Cái nào sẽ hoạt động (chủ yếu) giống như trong bash, vì đó là thư viện GNU Readline thực hiện công việc. Trang chủ của readline mô tả chi tiết các tính năng.
ulidtko

2
Ngoài ra, Ctl-UpArrow (hoặc AltUpArrow trên bash) sẽ cuộn ngược qua danh sách lịch sử. Nhập một vài ký tự thì UpArrow chỉ nhận được các lệnh bắt đầu bằng chữ cái đó, ví dụ: "fr (Ctl-Up)" cuộn qua tất cả các lệnh "miễn phí ..." trong danh sách của OP. Điều này cũng hoạt động trong những thứ như gnuplot & gdb sử dụng readline.
jamesqf

2
@ Ajedi32, xem dòng in đậm cuối cùng trong câu trả lời của tôi. :) Thực sự câu trả lời này chỉ là một hương vị của những gì mở rộng lịch sử có thể làm . Hãy nhớ rằng đây là cấp độ của vỏ, không phải là lệnh bạn đang gọi; do đó echo {1..5}tiếp theo touch !$sẽ chạm vào năm tệp, không chỉ một. Vì vậy, nói đúng ra đây không phải là đối số cuối cùng mà là từ vỏ cuối cùng trên dòng đó. (Cũng thử echo hello >temptheo sau echo goodbye !$.) Nếu bạn có thể nghĩ ra một cách để đặt nó rõ ràng hơn, hãy đề nghị chỉnh sửa.
Wildcard

14

Một cái hay, nếu bạn không muốn lịch sử đầu tiên, hãy lưu ý số, v.v .:

trong bash (và có thể những người khác):

ctrl-r something 

( ctrl-r= "tìm kiếm ngược tương tác") ( something= một phần của lệnh trước đó)

Điều này sẽ cho bạn thấy dòng lịch sử mới nhất có chứa something. Để lấy cái trước, hãy thực hiện lại ctrl-r (một mình), mỗi lần nó nhận được một dòng trước đó.

Ví dụ:

ctrl-r  10

để hiển thị dòng lịch sử mới nhất chứa '10' (ví dụ như dòng với $10, trong ví dụ của bạn) và ctrl-rmột lần nữa cho đến khi bạn truy xuất dòng lịch sử mà bạn đang tìm kiếm

Khi dòng bạn muốn xuất hiện, chỉ cần Enterchạy nó (hoặc bạn cũng có thể chỉnh sửa nó, bằng cách sử dụng arrow keys, backspacectrl-ađể đi đến đầu dòng, ctrl-eđể có được kết thúc, ctrl-k: để "giết" từ con trỏ đến cuối dòng (= xóa + lưu nó trong bộ đệm) , ctrl-y: để khôi phục, từ bộ đệm, một bit đã bị hủy trước đó, v.v.)

Nếu bạn muốn tìm kiếm về phía trước (ctrl-s), trước tiên bạn cần tắt XON : xem https://stackoverflow.com/a/791800/1841533 :

"chỉ để vô hiệu hóa XON / XOFF bằng cách chạy

stty -ixon

"(Và sau đó bạn sẽ có thể sử dụng ctrl-s mà không cần đóng băng thiết bị đầu cuối)


Nếu tôi làm điều này và vô tình nhấn ctrl-r một lần quá nhiều, có cách nào để tìm kiếm lại trong lịch sử không?
kasperd

@kasperd: Có bạn có thể. nhiều câu trả lời trên se chỉ ra: ctrl-s cho tìm kiếm chuyển tiếp.
Olivier Dulac

Thật không may, ctrl-s được sử dụng để đóng băng thiết bị đầu cuối và bash không vô hiệu hóa điều đó, do đó, nó không hoạt động trong cấu hình mặc định. (Các chương trình khác - chẳng hạn như emacs - vô hiệu hóa các keybinding để đóng băng các thiết bị đầu cuối như vậy ctrl-s có thể được sử dụng để tìm kiếm.)
kasperd

@kasperd: Vâng, xin lỗi vì đã không đề cập đến điều đó sớm hơn .. điện thoại) bây giờ tôi trở về nhà và có thể chỉnh sửa trong các câu trả lời trên ctrl-s cho tìm kiếm lịch sử bash cần bạn stty -ixon đầu tiên
Olivier Dulac

Lệnh đó sẽ phá vỡ việc sử dụng ctrl-s bình thường, vì vậy đó không thực sự là một lựa chọn.
kasperd

7

Bạn có thể sử dụng shell dựng sẵn fc :

fc -s 636

2
Điều này thực sự tốt hơn câu trả lời được chấp nhận, nhưng bạn phải loại bỏ -sđể có được lợi ích. Nếu bạn chạy, fc 636bạn sẽ mở một trình soạn thảo với lệnh 636 từ lịch sử của bạn trong bộ đệm và khi bạn lưu và thoát lệnh (có sửa đổi hay không) sẽ được chạy. Và thậm chí tốt hơn, cái này là tuân thủ POSIX .
tự đại diện

@StevenPenny Cảm ơn. Và vâng, tôi biết POSIX là gì, mặc dù tôi không thấy sự liên quan. Bất kể, một số tài liệu dễ dàng truy cập và bao gồm sẽ là tốt đẹp.
Faheem Mitha

@FaheemMitha hãy thử chạy "trợ giúp fc."
tự đại diện

@Wildcard helpkhông phải là POSIX - có thể phải làm man dashhoặc tương tự
Steven Penny

@Wildcard Cảm ơn. Tôi có xu hướng quên helptồn tại. Một vỏ khác dựng sẵn. Và khó hiểu cho những người dùng bất đắc dĩ, những người có thể muốn giúp đỡ với một hệ thống mới, nhưng thay vào đó lại phải đối mặt với một dòng vô nghĩa. :-(
Faheem Mitha

3

HSTR- hhlệnh cho bashzshlựa chọn lệnh tương tác, tốt hơn so với tìm kiếm ngược Ctrl-R:

hh ví dụ lệnh lịch sử tương tác

tương tác của nó, vì vậy bạn có thể tìm kiếm và chỉnh sửa lệnh trước khi thực hiện.

Trên Ubuntu, bạn có thể cài đặt hhvới một lớp lót sau:

sudo add-apt-repository ppa:ultradvorka/ppa && sudo apt-get update && sudo apt-get install hh && hh --show-configuration >> ~/.bashrc

hoặc từng bước:

sudo add-apt-repository ppa:ultradvorka/ppa
sudo apt-get update
sudo apt-get install hh

Cài đặt hhtrên Fedora, RHEL hoặc CentOS:

sudo dnf|yum install hstr -y

Trên macOS với homebrew:

brew install hh

... sau đó cấu hình nó với:

hh --show-configuration >> ~/.bashrc

Điều này sẽ thay thế hành vi Ctrl-R mặc định.

Chạy hh --show-configurationđể xác định những gì sẽ được thêm vào hồ sơ Bash của bạn.

Các tùy chọn cấu hình khác có sẵn trên trang chủ của dự án tại Github: https://github.com/dvorka/hstr

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.