Usuń określoną linię z pliku historii Bash

Odpowiedzi:

108

Musisz się wylogować i ponownie zalogować lub uruchomić, history -aaby bieżąca historia została zapisana na dysku.

Następnie po prostu edytuj plik ~/.bash_history.

Cyrus
źródło
19
Jeśli ustawiona jest zmienna środowiskowa HISTFILE, plik historii to nie ~ / .bash_history, a raczej $ {HISTFILE}.
Karolos,
20
Wpisy są zapisywane w pliku historii po wyjściu z powłoki. Dlatego po wprowadzeniu polecenia, które chcesz usunąć, musisz się wylogować i zalogować ponownie lub użyć polecenia „history -d xxxx”, aby usunąć je z bieżącej sesji powłoki.
harmic
3
ale jak usunąć zapis edycji pliku historii?
chiliNUT
5
@chiliNUT: Po prostu uruchom polecenie (np. vim ~/.bash_history) ze spacją; polecenia zaczynające się od spacji zwykle nie są rejestrowane (patrz $HISTCONTROL).
cyr
Nie sądzę, że tak jest w mojej dystrybucji, ale ogólnie ma to sens
chiliNUT
149

Usunięcie z pliku historii można osiągnąć za pomocą wiersza polecenia w dwóch krokach:

  1. Wpisanie history -d <line_number>usuwa określony wiersz z historii w pamięci.
  2. Wpisanie history -wzapisuje bieżącą historię w pamięci do ~/.bash_historypliku.

Te dwa kroki razem trwale usunąć wiersz z pamięci w historii iz .bash_history pliku, jak również.

Paperlantern
źródło
7
jak usunąć ostatni history -wz historii?
KrisHnA
@KrIsHnA edytuj ~ / .bash_history ręcznie
Alexander Myshov
5
Lub dodaj spację, aby zapobiec dodaniu, jak w odpowiedzi @ tao
Mark,
Aby znaleźć <line_number>tylko history | grep [unwanted_content]uzyskać listę ze wszystkimi wierszami zawierającymi [unwanted_content](jak hasła).
AvL
Jak usunąć wiele (określonych) wierszy (według identyfikatora)?
Pathros,
39

Aby przede wszystkim zapobiec dodawaniu polecenia do historii, upewnij się, że zmienna środowiskowa HISTCONTROLzawiera między wartościami oddzielonymi dwukropkami wartość ignorespace, na przykład (dodaj np. Do .bashrc):

$ export HISTCONTROL=ignorespace

Zapobiegnie to dodaniu do historii poleceń z wiodącym odstępem. Następnie możesz całkowicie wyczyścić historię, uruchamiając

$  history -c -w
  ^-- additional space character
tao
źródło
32

Przede wszystkim, jeśli polecenie, które zamierzasz wydać, jest wrażliwe, niebezpieczne lub po prostu nie potrzebujesz go zaśmiecać w swojej historii, najlepiej / najszybciej jest po prostu uniemożliwić jego wejście do historii. Upewnij się, że $HISTCONTROLzawiera ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Następnie wykonaj dowolne polecenie, którego nie chcesz w swojej historii, spacją:

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

Jeśli przypadkowo umieścisz niechciane polecenie w historii, pod warunkiem, że twoja sesja bash jest nadal otwarta, polecenie jeszcze nie dotknęło dysku. Aby usunąć poprzednie polecenie z historii, wydaj:

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

Zwróć uwagę na wiodące miejsce; to polecenie wymaga ignorespace, w przeciwnym razie po prostu się skasuje!

Jeśli chcesz usunąć kilka ostatnich poleceń, znajdź ostatni i pierwszy numer historii:

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

W tym przypadku 602 i 599. Następnie wydaj:

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

(Bez ignorespacebyłoby to 603..599.)

Jeśli nie chcesz, aby jakaś historia z bieżącej sesji trafiła na dysk, wyjdź, używając:

(bash)$ kill -9 $$

Dotychczasowe podejście polegało na tym, aby nawet nie zapisywać wrażliwych elementów historii na dysku dla dodatkowego bezpieczeństwa, ponieważ teoretycznie dane usunięte z nieulotnych nośników można nadal odzyskać.

Jeśli jednak polecenia, które chcesz usunąć, pochodzą z poprzedniej sesji, zostaną już dołączone do $HISTFILEwyjścia. Manipulowanie historią za pomocą powyższych poleceń nadal dołącza tylko pozostałe nowe elementy do $HISTFILE, przy wyjściu . Aby nadpisać$HISTFILE z widokiem na bieżącej sesji użytkownika w całej historii, w tej chwili , issue:

(bash)$  history -w

Oczywiście w przypadku elementów historii znajdujących się już na dysku alternatywą do edycji historii za pomocą history -dpoleceń, a następnie wydawania history -w, jest edycja $HISTFILEza pomocą edytora tekstu.

James Haigh
źródło
1
„Manipulowanie historią z powyższych poleceń będzie nadal tylko dołączyć pozostałych nowych elementów do $HISTFILE, na wyjściu ”. Faktycznie, nie jest to do końca prawda. Wydaje się, że dołącza tylko pozostałe nowe elementy, które „wystają” z pierwotnej długości historii. Np. Jeśli usunę 5 oryginalnych elementów i dodam 15 nowych, dołączonych zostanie tylko 10 ostatnich, podczas gdy oczekuję, że wszystkie 15 nowych zostanie dołączonych. Myślę, że to błąd, ponieważ nie widzę, jak to zawsze jest pożądana funkcjonalność.
James Haigh,
1
Myślę, że bash bierze pod uwagę oryginalną długość. Przy zamknięciu sesji przypuszczalnie dołącza elementy, których liczba jest większa niż ta wartość. Jeśli wartość ta była zmniejszana za każdym razem, gdy usuwany jest element, którego liczba jest mniejsza lub równa tej wartości, działałoby to zgodnie z oczekiwaniami. ;-)
James Haigh,
15

Kilka technik:

Zapobiegaj przechowywaniu poufnych informacji w pliku historii

Jeśli wpiszesz jakieś hasło w wierszu poleceń, to wiedz, że wszystkie polecenia są zarejestrowane, możesz:

  1. Wymuś wyjście z bieżącej sesji bez zapisywania historii:

     kill -9 $$

    Spowoduje to usunięcie całej bieżącej historii.

  2. Wpisz ↑ (up arrow)sesję otwartej bash, aż zostaną wyświetlone poufne informacje, a następnie użyj klawiszy edycji linii, takich jak Ctrl+, Waby usunąć wrażliwe informacje, a następnie ↓ (down arrow) do momentu wyświetlenia monitu o nową pustą linię, zanim zaczniesz pisać Enter.

Usuń poufne informacje z pliku historii

Jeśli zdajesz sobie sprawę, że poufne informacje są już przechowywane i chcesz je usunąć, ale nie całą historię:

Proste sedpolecenie może wykonać zadanie:

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

ale podczas wpisywania tworzona jest kolejna linia historii zawierająca wzorzec wyszukiwania (informacje poufne), który próbujesz usunąć. Więc możesz:

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

To będzie działać head -n1z wejściem z terminala. Wygląda na to, że twój terminal jest zawieszony (nie pojawi się monit); po prostu wpisz informacje, które chcesz usunąć z pliku. Jest to sztuczka pozwalająca na wprowadzenie (części) polecenia bez wpisywania go w wierszu poleceń, przez co nie można go włączyć do rekordu historii. Następnie sedużyje wpisanego tekstu, aby wyszukać .bash_history i usunąć wszystkie wiersze zawierające poufne informacje. Uwaga: jeśli wzorzec poufnych informacji zawiera ukośniki, musisz je uciec za pomocą ukośników odwrotnych lub zmienić sedpolecenie, aby użyć tej składni, aby określić separator, który nie pojawia się we wzorcu:

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

Innym sposobem może być usunięcie tylko poufnych informacji, ale zachowanie poleceń zawierających te informacje. W tym celu możesz po prostu zastąpić poufne informacje wybranym tekstem zastępczym:

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

Usuń poufne informacje z dowolnego pliku w określonym drzewie

Na koniec, aby upewnić się, że nie pozostanie w innym zapomnianym pliku:

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

wyświetli listę wszystkich zainteresowanych plików.

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

zastąpi wszystkie wystąpienia poufnych informacji we wszystkich plikach w drzewie katalogów zrootowanym .. Uwaga: nawet jeśli to polecenie używa xargs -0, nie obsługuje plików z nowymi liniami w nazwach.

F. Hauri
źródło
11

Znajdź wiersz, który chcesz usunąć, naciskając, ↑ (up arrow)aż się pojawi, a następnie naciśnij Ctrl+ U. To powinno usunąć linię.

Jeśli użyjesz historypolecenia, zobaczysz, że linia została zastąpiona gwiazdką.

Vicentecarro
źródło
2
Właściwie uważam, że musisz kursor w górę do linii, naciśnij Ctrl + U, a następnie przesuń kursor w górę lub w dół do innej linii (być może pustej linii na dole listy). Ponadto, ściśle mówiąc, linia nie została zastąpiona gwiazdką. Zamiast tego polecenie zostało usunięte, a do numeru historii dodano znak *.
G-Man,
1
Staje się to o wiele potężniejsze dzięki Ctrl + R (odwrotne przyrostowe wyszukiwanie historii), a następnie np. [End], Ctrl + U
patrz
4

Jeśli chcesz usunąć kilka linii jednocześnie, zwykle używam tego:

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

Jeśli chcesz usunąć ostatnie polecenie, możesz użyć:

history -d $((HISTCMD-2))
Więź
źródło
2
To wyglądało tak, jakby działał, ale history | grep <string>nadal pokazuje wszystkie linie Twierdzi, aby usunąć ...
Brock Hensley
1
Spowoduje to usunięcie niewłaściwych wierszy historii po usunięciu pliku fisrt !!
mivk,
1
Ale na szczęście drukuje tylko nieprawidłowe polecenia usuwania. Następujące polecenia wydrukują prawidłowe polecenia usuwania:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk
3

Jeśli musisz usunąć zakres linii z historii, następująca funkcja bash może zaoszczędzić trochę czasu:

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
}

Funkcja powinna być zazwyczaj dodawana do $HOME/.bashrc. Aby użyć tej funkcji bezpośrednio, musisz ponownie odczytać plik przez działającą powłokę ( . $HOME/.bashrc). Następnie, aby usunąć np. Polecenia 200-210 z historii:

$ histdel 200 210

(Uwaga: to pytanie jest jednym z najlepszych wyników wyszukiwania, jeśli szukasz usunięcia szeregu poleceń z historii bash. Tak więc, chociaż powyższe jest więcej niż to, o co pyta pytanie, może być przydatne dla niektórych czytelników.)

m000
źródło
3
Alternatywne formy foroświadczenia: for n in $(seq "$2" "$1")jest przez niektórych preferowany stylistycznie, a jeśli seqnie działa, spróbuj for ((n="$2"; n>="$1"; n--)).
Scott
3
history | sed -i 59d

59 to numer linii. Nie może być nic słodszego niż to :)

KroKite
źródło
3

Po prostu spróbuj tych

$ history

to wyświetli identyfikator historii i polecenia, np

.
.
211 ls
212 javac Welcome.java
213 java welcome
.
.

posługiwać się,

$ history -d 211

Tutaj 211 jest id historii. Teraz sprawdź to za pomocą

$ history

.
.
211 javac Welcome.java
212 java welcome
.
.

użytkownik3378188
źródło
2

Wiem, że minęło dużo czasu, odkąd pytanie zostało zadane i udzielono odpowiedzi, ale pokażę ci moją metodę czyszczenia mojego pliku historii i wylogowywania się w tym samym czasie.

Biegnę : history -w && nano "${HISTFILE}" && history -c && exit

To, co robi, jest proste:

  1. history -w : zapisuje w pamięci podręczną historię "${HISTFILE}"
  2. nano "${HISTFILE}": pozwól mi edytować "${HISTFILE}"Możesz użyć skryptu sed lub cokolwiek chcesz wyczyścić"${HISTFILE}"
  3. history -c : wyczyść historię buforowaną, aby to ostatnie polecenie nie było dołączane.
  4. exit : wyloguj mnie dołączając historię z pamięci podręcznej ... ale jest pusta;)

Po tym poleceniu nastąpi wylogowanie z czystym plikiem historii. Zaloguj się, aby sprawdzić swoją historię;)

Mam nadzieję, że to komuś pomoże.

ncenerar
źródło
1

Możesz także edytować plik historii bezpośrednio, np. nano .bash_historyJeśli jesteś w powłoce bash?

Ptaszyna
źródło