Xóa một dòng nhất định khỏi tệp lịch sử Bash


Câu trả lời:


108

Bạn cần phải đăng xuất và đăng nhập lại hoặc chạy history -ađể lịch sử hiện tại được cam kết vào đĩa.

Sau đó chỉ cần chỉnh sửa các tập tin ~/.bash_history.


19
Nếu biến môi trường HISTFILE được đặt, tệp lịch sử không phải là ~ / .bash_history mà là $ {HISTFILE}.
Karolos

20
Các mục được ghi vào tệp lịch sử khi bạn thoát khỏi trình bao. Do đó, sau khi nhập lệnh mà bạn muốn xóa, bạn cần đăng xuất và đăng nhập lại hoặc sử dụng 'history -d xxxx' để xóa chúng khỏi phiên shell hiện tại.
hại

3
nhưng làm thế nào bạn sẽ xóa bản ghi chỉnh sửa tập tin lịch sử?
ớt

5
@chiliNUT: Chỉ cần bắt đầu lệnh của bạn (ví dụ vim ~/.bash_history) bằng khoảng trắng ; các lệnh bắt đầu bằng một khoảng trắng thường không được ghi lại (xem $HISTCONTROL).
cYrus

Tôi không nghĩ đó là trường hợp trong bản phân phối của tôi, nhưng nói chung điều đó có ý nghĩa
chiliNUT

149

Bạn có thể đạt được xóa khỏi tệp lịch sử bằng cách sử dụng dòng lệnh theo hai bước:

  1. history -d <line_number>xóa một dòng xác định từ lịch sử trong bộ nhớ.
  2. Nhập history -wvăn bản ghi lịch sử trong bộ nhớ hiện tại vào ~/.bash_historytập tin.

Hai bước cùng nhau xóa dòng vĩnh viễn khỏi lịch sử trong bộ nhớ và từ tệp .bash_history .


7
Làm thế nào để xóa cuối cùng history -wtừ lịch sử?
KrIsHnA

@KrIsHnA chỉnh sửa ~ / .bash_history bằng tay
Alexander Myshov

5
Hoặc thêm một không gian trước khi nó để ngăn chặn nó được thêm vào, như trong câu trả lời @ Tao
Đánh dấu

Để tìm <line_number>chỉ history | grep [unwanted_content]để có được một danh sách với tất cả các dòng chứa [unwanted_content](như mật khẩu).
AvL

Làm thế nào để bạn xóa nhiều dòng (cụ thể) (theo id)?
Pathros

39

Để ngăn lệnh được thêm vào lịch sử ở vị trí đầu tiên, hãy đảm bảo rằng biến môi trường HISTCONTROLchứa trong số các giá trị được phân tách bằng dấu hai chấm của nó ignorespace, ví dụ (thêm ví dụ vào .bashrc):

$ export HISTCONTROL=ignorespace

Điều này sẽ ngăn bất kỳ lệnh nào có không gian hàng đầu được thêm vào lịch sử. Sau đó bạn có thể xóa lịch sử hoàn toàn bằng cách chạy

$  history -c -w
  ^-- additional space character

32

Trước hết, nếu lệnh bạn sắp phát hành là nhạy cảm, không an toàn hoặc bạn không cần nó làm lộn xộn lịch sử của bạn, thì tốt nhất / nhanh nhất là chỉ ngăn không cho nó đi vào lịch sử ngay từ đầu. Đảm bảo $HISTCONTROLcó chứa ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Sau đó tiến hành bất kỳ lệnh nào bạn không muốn trong lịch sử của mình với một khoảng trắng:

(bash)$  sensitive-cmd-with --password 82cf7dfe
(bash)$  rm -r... # One-off recursive remove; mustn't be accidentally repeated!

Nếu bạn vô tình đưa một lệnh không mong muốn vào lịch sử, miễn là phiên bash của bạn vẫn mở, lệnh vẫn chưa chạm vào đĩa. Để xóa lệnh trước đó trong lịch sử, hãy phát hành:

(bash)$  history -d $((HISTCMD-1))

Lưu ý không gian hàng đầu; Lệnh này yêu cầu ignorespace, nếu không nó sẽ tự xóa!

Nếu bạn muốn xóa một vài lệnh cuối cùng, hãy tìm số lịch sử cuối cùng và đầu tiên:

(bash)$  history 5
  598  ok
  599  sensitive
  600  unsafe
  601  doesn\'t-work
  602  otherwise-unwanted

Trong trường hợp này là 602 và 599. Sau đó, phát hành:

(bash)$  for i in {602..599}; do history -d $i; done

(Nếu không ignorespace, nó sẽ là 603..599.)

Nếu bạn không muốn bất kỳ lịch sử nào từ phiên hiện tại của mình vào đĩa, hãy thoát bằng:

(bash)$ kill -9 $$

Cách tiếp cận cho đến nay là thậm chí không để các mục lịch sử nhạy cảm được ghi vào đĩa để bảo mật hơn, bởi vì trong lý thuyết, dữ liệu bị xóa khỏi phương tiện không bay hơi vẫn có thể được phục hồi.

Tuy nhiên, nếu (các) lệnh bạn muốn loại bỏ là từ phiên trước đó, thì chúng sẽ được thêm $HISTFILEvào lối ra. Thao tác lịch sử với các lệnh trên sẽ vẫn chỉ nối các mục mới còn lại vào $HISTFILE, khi thoát . Để ghi đè lên các $HISTFILEvới quan điểm của phiên hiện tại của của toàn bộ lịch sử, ngay bây giờ , vấn đề:

(bash)$  history -w

Tất nhiên đối với các mục lịch sử đã có trên đĩa, cách thay thế để chỉnh sửa lịch sử bằng history -dcác lệnh sau đó ban hành history -w, là chỉnh sửa $HISTFILEbằng trình soạn thảo văn bản.


1
Ban điều khiển lịch sử với các lệnh trên sẽ vẫn chỉ nối thêm các mục mới còn lại vào $HISTFILE, khi thoát . Thực tế, điều này không chính xác. Dường như chỉ nối thêm các mục mới còn lại 'dính ra' từ chiều dài lịch sử ban đầu. Ví dụ: Nếu tôi xóa 5 mục gốc và thêm 15 mục mới, chỉ có 10 mục mới được thêm vào, trong khi tôi hy vọng tất cả 15 mục mới sẽ được thêm vào. Tôi nghĩ rằng đây là một lỗi vì tôi không thể thấy đây là chức năng mong muốn như thế nào.
James Haigh

1
Tôi đoán bash lưu ý về chiều dài ban đầu. Khi đóng phiên, có lẽ nó sẽ nối thêm các mục có số lớn hơn giá trị này. Nếu giá trị này bị giảm đi mỗi khi một mục bị xóa có số lượng nhỏ hơn hoặc bằng giá trị này, nó sẽ hoạt động như mong đợi. ;-)
James Haigh

15

Một số kỹ thuật:

Ngăn chặn thông tin nhạy cảm được lưu trữ trong tệp lịch sử

Nếu bạn đã nhập một số mật khẩu trên một dòng lệnh, sau đó nhận ra rằng tất cả các lệnh được ghi lại, bạn có thể:

  1. Buộc thoát phiên hiện tại mà không lưu lịch sử:

     kill -9 $$

    Điều này sẽ bỏ tất cả lịch sử hiện tại.

  2. Loại ↑ (up arrow)trong phiên bash mở cho đến khi thông tin nhạy cảm được hiển thị, sau đó sử dụng tổ hợp phím chỉnh sửa dòng như Ctrl+ Wđể xóa các thông tin nhạy cảm, và sau đó ↓ (down arrow) cho đến khi một dòng trống mới được nhắc, trước khiEnter.

Xóa thông tin nhạy cảm khỏi tệp lịch sử

Nếu bạn nhận ra rằng thông tin nhạy cảm đã được lưu trữ và bạn muốn xóa nó, nhưng không phải toàn bộ lịch sử của bạn:

Một sedlệnh đơn giản có thể thực hiện công việc:

sed -e '/SeNsItIvE InFo/d' -i .bash_history

nhưng, khi bạn nhập này, bạn tạo một dòng lịch sử khác chứa mẫu tìm kiếm (thông tin nhạy cảm) mà bạn đang cố xóa. Vì vậy, bạn có thể:

sed -e "/$(head -n1)/d" -i .bash_history

Điều này sẽ chạy head -n1với đầu vào từ thiết bị đầu cuối. Dường như thiết bị đầu cuối của bạn bị treo (sẽ không có dấu nhắc); chỉ cần nhập thông tin mà bạn muốn xóa khỏi tập tin. Đây là một mẹo để cho phép bạn nhập (một phần) một lệnh mà không thực sự nhập nó vào dòng lệnh, do đó làm cho nó không đủ điều kiện để đưa vào bản ghi lịch sử. Sau đó sedsẽ sử dụng văn bản mà bạn đã nhập để tìm kiếm .bash_history và xóa tất cả các dòng có chứa thông tin nhạy cảm. Lưu ý: nếu mẫu thông tin nhạy cảm của bạn chứa dấu gạch chéo, bạn phải thoát chúng bằng dấu gạch chéo ngược hoặc nếu không thì thay đổi sedlệnh để sử dụng cú pháp này để chỉ định một dấu phân cách không xuất hiện trong mẫu:

sed -e "\|$(head -n1)|d" -i .bash_history

Một cách khác có thể là chỉ xóa thông tin nhạy cảm, nhưng giữ các lệnh có chứa thông tin. Đối với điều này, bạn chỉ có thể thay thế thông tin nhạy cảm bằng văn bản thay thế bạn chọn:

sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.

Xóa thông tin nhạy cảm khỏi bất kỳ tệp nào trong một cây cụ thể

Cuối cùng, để chắc chắn rằng điều này sẽ không ở trong một tập tin bị lãng quên khác :

SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"

sẽ liệt kê tất cả các tập tin liên quan.

find . -type f -print0 |
    xargs -0 grep -l "$SENSITIVEINFO" |
    tr \\n \\0 |
    xargs -0 sed -e "s/$SENSITIVEINFO/Santa Claus/g" -i

sẽ thay thế tất cả các lần xuất hiện của thông tin nhạy cảm trong tất cả các tệp trong cây thư mục gốc .. Lưu ý: mặc dù lệnh này sử dụng xargs -0, nó sẽ không xử lý các tệp có dòng mới trong tên của chúng.


11

Xác định vị trí dòng bạn muốn xóa bằng cách nhấn ↑ (up arrow)cho đến khi nó xuất hiện, sau đó nhấn Ctrl+ U. Điều đó sẽ loại bỏ các dòng.

Nếu bạn sử dụng historylệnh, bạn có thể thấy dòng đã được thay thế bằng dấu hoa thị.


2
Trên thực tế, tôi tin rằng bạn phải con trỏ lên đến dòng, nhấn Ctrl + U và sau đó con trỏ lên hoặc xuống dòng khác (có thể là dòng trống ở cuối danh sách). Ngoài ra, nói đúng ra, dòng này đã không được thay thế bằng dấu hoa thị. Thay vào đó, lệnh đã bị xóa và số lịch sử đã được thêm vào a *.
G-Man

1
Điều này trở nên mạnh mẽ hơn nhiều với Ctrl + R (tìm kiếm lịch sử gia tăng ngược), sau đó, ví dụ [Kết thúc], Ctrl + U
sehe

4

Nếu bạn cần loại bỏ một vài dòng cùng một lúc tôi thường sử dụng điều này:

history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'

Nếu bạn cần loại bỏ lệnh cuối cùng, bạn có thể sử dụng:

history -d $((HISTCMD-2))

2
Điều này trông giống như nó hoạt động nhưng history | grep <string>vẫn hiển thị tất cả các dòng mà nó tuyên bố sẽ xóa ...
Brock Hensley

1
Điều này sẽ xóa các dòng lịch sử sai sau khi xóa fisrt !!
mivk

1
Nhưng may mắn thay, nó chỉ in các lệnh xóa sai. Sau đây sẽ in các lệnh xóa chính xác:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk 20/12/13

3

Nếu bạn cần xóa một loạt các dòng khỏi lịch sử, hàm bash sau có thể giúp bạn tiết kiệm thời gian:

function histdel() {
    [ $# -eq 1 ] && history -d "$1" && history -w
    if [ $# -eq 2 -a "$1" -le "$2" ]; then
        for n in `seq "$2" "$1"`; do
            history -d "$n"
        done
        history -w
    fi
}

Chức năng thường được thêm vào $HOME/.bashrc. Để sử dụng hàm imediatelly, bạn sẽ cần phải đọc lại tệp bằng shell đang chạy ( . $HOME/.bashrc). Sau đó, để xóa các lệnh 200-210 từ lịch sử:

$ histdel 200 210

(Lưu ý: Câu hỏi này nằm trong số các kết quả tìm kiếm hàng đầu nếu bạn tìm kiếm để xóa một loạt các lệnh khỏi lịch sử bash. Vì vậy, trong khi ở trên nhiều hơn những gì câu hỏi yêu cầu, nó có thể hữu ích cho một số độc giả.)


3
Các hình thức thay thế cho fortuyên bố: for n in $(seq "$2" "$1")được một số người ưa thích theo phong cách, và, nếu seqkhông hoạt động, hãy thử for ((n="$2"; n>="$1"; n--)).
Scott

3
history | sed -i 59d

59 là số dòng. Không thể có gì ngọt ngào hơn thế này :)


3

Hãy thử những thứ này,

$ history

điều này sẽ hiển thị id của lịch sử và lệnh, vd

.
.
211 ls
212 javac Welcome.java
213 java chào mừng
.
.

sử dụng,

$ history -d 211

Ở đây 211 là id của lịch sử. Bây giờ hãy kiểm tra điều này bằng cách sử dụng

$ history

.
.
211 javac Welcome.java
212 java chào mừng
.
.


2

Tôi biết đã lâu rồi kể từ khi câu hỏi này được hỏi và trả lời nhưng tôi sẽ chỉ cho bạn phương pháp để làm sạch tệp lịch sử của mình và đăng xuất cùng một lúc.

Tôi chạy : history -w && nano "${HISTFILE}" && history -c && exit

Những gì nó làm là đơn giản:

  1. history -w : ghi lịch sử lưu trữ bên trong "${HISTFILE}"
  2. nano "${HISTFILE}": cho phép tôi chỉnh sửa "${HISTFILE}"Bạn có thể sử dụng tập lệnh sed hoặc bất cứ điều gì bạn muốn để làm sạch"${HISTFILE}"
  3. history -c : xóa lịch sử lưu trữ để lệnh cuối cùng này không được nối.
  4. exit : đăng xuất cho tôi thêm lịch sử lưu vào bộ nhớ cache ... nhưng nó trống;)

Sau lệnh đó, bạn sẽ được đăng xuất với một tệp lịch sử sạch. Đăng nhập để kiểm tra lịch sử của bạn;)

Tôi hy vọng điều này sẽ giúp được ai đó.


1

Bạn cũng có thể chỉnh sửa tệp lịch sử trực tiếp, ví dụ: nano .bash_historynếu bạn đang ở trong bash shell?

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.