đưa lệnh lịch sử vào dòng lệnh mà không thực hiện nó


57

Tôi sử dụng! N trong đó (n) là số dòng để thực thi một dòng trong tệp lịch sử mà tôi muốn thực hiện tại dấu nhắc lệnh mà tôi tìm thấy qua history | less.

Nhưng có một sự kiện lịch sử dòng lệnh tôi muốn sửa đổi bằng tay. Làm thế nào tôi có thể chèn vào dòng lệnh một nội dung sự kiện lịch sử mà không thực sự thực thi để tôi có thể sửa đổi và sau đó nhấn return?

Tốt,

Câu trả lời:


71

Để yêu cầu lệnh được in thay vì được thực thi sau khi thay thế lịch sử, hãy thêm công cụ :p sửa đổi , vd !42:p. Lệnh kết quả cũng sẽ được nhập vào lịch sử, vì vậy bạn có thể nhấn Upđể chỉnh sửa nó.

Nếu bạn có histverify tùy chọn được đặt ( shopt -s histverify), bạn sẽ luôn có cơ hội chỉnh sửa kết quả của các thay thế lịch sử.

Các fcBUILTIN cho phép truy cập hạn chế việc mở rộng lịch sử (không định danh từ), và cho phép bạn chỉnh sửa một lệnh trước đó trong một biên tập viên bên ngoài.

Bạn có thể sử dụng !prefixđể tham khảo lệnh cuối cùng bắt đầu bằng prefix!?substringđể chỉ lệnh cuối cùng bắt đầu bằng substring. Khi bạn biết những gì bạn đang tìm kiếm, điều này có thể tiết kiệm rất nhiều thời gian hơn history | less.

Một cách khác để tìm kiếm trong lịch sử trước đó là tìm kiếm gia tăng: nhấn Ctrl+ Rvà bắt đầu nhập một chuỗi con của những gì bạn đang tìm kiếm. Nhấn Ctrl+ Rđể đi đến sự xuất hiện trước đó của chuỗi tìm kiếm cho đến nay và Ctrl+ Snếu bạn đã đi quá xa. Hầu hết các phím khác hơn Ctrl+ R, Ctrl+ S, Backspacevà các nhân vật bình thường chấm dứt việc tìm kiếm gia tăng và có hiệu lực thi hành thông thường (ví dụ như các phím mũi tên để di chuyển con trỏ vào dòng bạn đã đạt được, họ Enterđể chạy các lệnh).


Có một lỗi đánh máy trong ví dụ đầu tiên của bạn ...
pbm

9
Bạn sẽ cần phải làm stty -ixontrước khi Ctrl-s hoạt động.
Dennis Williamson

@Dennis: Wow, trình giả lập thiết bị đầu cuối hiện đại không làm điều này theo mặc định? <test> Bạn đã đúng, ngay cả gnome-terminal trong Ubuntu cũng có kiểm soát luồng!
Gilles 'SO- ngừng trở nên xấu xa'

Tôi không biết tại sao họ vẫn làm. Không thể bắt được thứ gì đó trong khi nó đang cuộn. Khi bạn nhấn Ctrl-s, bạn sẽ có một lời nhắc lại. Và các kết nối nối tiếp chậm chủ yếu là một điều của quá khứ.
Dennis Williamson

Quan điểm của @ Dennis Ctrl-slà quan trọng, nếu không thì người ta bị kẹt như tôi đã làm .
imz - Ivan Zakharyaschev

15

Một số nhỏ khác: Alt+#

nhận xét dòng hiện tại và di chuyển nó vào bộ đệm lịch sử.

Vì vậy, khi bạn lắp ráp một dòng lệnh và bạn cần đưa ra một lệnh tạm thời, ví dụ như tìm một tệp, bạn chỉ cần nhấn Alt+ #, đưa ra lệnh khác, đi vào lịch sử, bỏ ghi chú và tiếp tục.


2
Ngoài ra Esc, #hoạt động
Steven Penny

và bạn thực sự có thể gõ nó trên máy mac (giữ shift, nhấn ESC và # cùng nhau), không giống như kết hợp ket khác (fn + alt + shift + #) ;-)
0xF2

7

Bạn có thể sử dụng không gian ma thuật để mở rộng lịch sử trước khi nhấn enter. Trong .inputrc của bạn, ánh xạ không gian vào không gian ma thuật:

$if Bash
     Space: magic-space
$endif

Bây giờ, bất cứ khi nào bạn nhập một khoảng trắng sau một đặc tả lịch sử, nó sẽ được mở rộng ngay lập tức - tiện dụng nếu bạn cũng muốn chỉnh sửa nó!



4

Sử dụng Ctrl+rbạn có thể tìm kiếm lịch sử:

pbm@tauri ~ $ 
(reverse-i-search)`xran': xrandr -o normal

Bất kỳ lệnh nào bạn tìm thấy đều có thể được chỉnh sửa ...


Tôi nghĩ rằng tôi đã tìm thấy chính xác những gì bạn cần: chạy shopt -s histverifyvà lần sau khi bạn muốn sử dụng !nlệnh sẽ không được thực thi mà chỉ được đưa vào dòng lệnh ...


Bạn phải thực thi một lệnh trước khi có thể tìm kiếm bằng Ctrl + r, không phải những gì Vass đang yêu cầu.
phunehehe

1
Tôi không hiểu làm thế nào điều này không làm những gì anh ấy yêu cầu. Tôi sẽ thêm rằng nếu trước tiên bạn muốn chỉnh sửa lệnh trước khi chạy nó, bạn chỉ cần nhấn TAB sau khi bạn đã tìm thấy lệnh đúng.
Steven D

2
Vì vậy, quy trình sẽ là, (1) Ctrl + r, (2) gõ cho đến khi bạn tìm thấy lệnh, (3) TAB, (4) lệnh chỉnh sửa, (5) ENTER.
Steven D

1
@phuenhehe: "Nhưng có một sự kiện lịch sử dòng lệnh tôi muốn sửa đổi thủ công"
pbm

1
Không !n:plàm việc à?
alex

1

Tôi thường muốn điều này. Khi tôi sử dụng csh (và tcsh), tôi đã có một thành ngữ:
!:88*:p

Thành ngữ này chèn "từ 88 đến từ cuối cùng" của lệnh trước đó tại điểm bạn đang gõ trên dòng lệnh hiện tại, thường là kết thúc. Trong csh, không có lỗi cho một biểu thức như vậy để không tạo ra từ. Đó là, không cần phải có một từ 88, cũng không có bất kỳ từ nào theo sau nó. Nếu không có từ 88, điều này sẽ không thêm từ nào vào cuối lệnh được gõ, và sau đó đẩy dòng lệnh kết quả vào lịch sử mà không thực hiện.

Như bạn có thể biết,
*! (như !! và! -1) là lệnh trước đó;
*: 88 là từ 88 (từ đầu tiên - thường là lệnh - bằng 0) và csh sẽ yêu cầu một từ như vậy tồn tại, nhưng ...
*: 88 * là tất cả các từ bắt đầu từ từ 88, và sau đó csh không yêu cầu từ tồn tại;
*: p có nghĩa là in, nhưng không thực thi dòng lệnh.
Có hoặc không có: p, dòng lệnh được thêm vào lịch sử lệnh.

"Tại sao 88?" bạn tự hỏi? Bởi vì nó là chìa khóa giống như * tôi sẽ cần. Nếu bạn có các lệnh dài, có lẽ !: 888 *: p là những gì bạn cần. Xin lỗi điều này không hoạt động với bash AFAIK. Bash sẽ chỉ nói bash: :88*: bad word specifier

Thực tế thú vị: lệnh của bạn thường không cần phải là đầu tiên.
> /tmp/foo echo My command is word 3
có giá trị trong bash và csh.


Vì câu hỏi được gắn thẻ cho bash, nên có thể tốt khi bắt đầu nói rằng giải pháp của bạn chỉ hoạt động trong (t) csh.
zagrimsan

0

Tôi thường sử dụng Ctrl+ rđể tìm kiếm và sau đó Ctrl+ eđể đi đến cuối dòng mà không thực hiện.



@JeffSchaller Tôi không thấy nó. Tôi thấy tham chiếu CTRL + R. Không có nơi nào tôi thấy CTRL + E là phần còn thiếu của câu đố trong các bài viết trên.
nikc
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.