Видаліть певний рядок із файлу історії Bash


Відповіді:


108

Потрібно вийти з системи та ввійти назад, або запустити його, history -aщоб поточна історія була зафіксована на диску.

Потім просто відредагуйте файл ~/.bash_history.


19
Якщо встановлена ​​змінна середовища HISTFILE, файл історії не ~ / .bash_history, а скоріше $ {HISTFILE}.
Каролос

20
Записи записуються у файл історії при виході з оболонки. Тому після введення команди, яку ви хочете видалити, вам потрібно або вийти з системи, і ввійти назад, або скористатися "історією -d xxxx", щоб видалити їх із поточного сеансу оболонки.
шкідливий

3
але як би ви видалили запис про редагування файла історії?
chiliNUT

5
@chiliNUT: Просто запустіть команду (наприклад vim ~/.bash_history) з пробілу; команди, що починаються з пробілу, зазвичай не реєструються (див. $HISTCONTROL).
cYrus

Я не думаю, що це так у моєму розповсюдженні, але загалом це має сенс
chiliNUT

149

Ви можете домогтися видалення з файлу історії за допомогою командного рядка в два етапи:

  1. Введення history -d <line_number>видаляє вказаний рядок з історії в пам'яті.
  2. Введення history -wзаписує у ~/.bash_historyфайл поточну історію пам’яті .

Два кроки разом видаляють рядок назавжди з історії пам'яті та з файлу .bash_history .


7
як видалити останнє history -wз історії?
KrIsHnA

@KrIsHnA редагувати ~ / .bash_history вручну
Олександр Мишов

5
Або додайте пробіл перед цим, щоб не додати його, як у відповіді @ tao
Марк

Щоб знайти <line_number>просто, history | grep [unwanted_content]щоб отримати список з усіма рядками, що містять [unwanted_content](наприклад, паролі).
Авл

Як видалити кілька (конкретних) рядків (за id)?
Патрос

39

Щоб запобігти додаванню команди в історію в першу чергу, переконайтеся, що змінна середовища HISTCONTROLмістить серед значень, розділених двокрапкою, значення ignorespace, наприклад (add eg to .bashrc):

$ export HISTCONTROL=ignorespace

Це не дозволить будь-якій команді з провідним пробілом бути доданим до історії. Потім можна повністю очистити історію, запустивши

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

32

Перш за все, якщо команда, яку ви збираєтеся видавати, є чутливою, небезпечною, або вам просто не потрібно, щоб вона захаращувала вашу історію, найкраще / швидше просто запобігти її введенню в історію в першу чергу. Переконайтеся, що він $HISTCONTROLмістить ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Потім виконайте пробіл будь-яку команду, яку ви не хочете в історії:

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

Якщо ви випадково ввели небажану команду в історію, за умови, що ваш сеанс bash все ще відкритий, команда ще не торкнулася диска. Щоб видалити попередню команду в історії, видайте:

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

Зверніть увагу на провідний простір; ця команда вимагає ignorespace, інакше вона просто видалить себе!

Якщо ви хочете видалити останні кілька команд, знайдіть останній та перший номер історії:

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

У цьому випадку 602 та 599. Потім видайте:

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

(Без ignorespaceцього було б 603..599.)

Якщо ви не хочете який - або історії з вашої поточної сесії вдарити диск, вихід з допомогою:

(bash)$ kill -9 $$

Досі підхід полягає в тому, щоб навіть не дозволяти записати чутливі предмети історії на диск для додаткової безпеки, оскільки теоретично дані, вилучені з енергонезалежних носіїв, все одно можуть бути відновлені.

Якщо, однак, команди, які ви хочете видалити, є з попереднього сеансу, вони вже будуть додані до $HISTFILEвиходу при виході. Маніпулювання історії з вищезгаданими командами буде ще тільки додати інші нові деталі до $HISTFILE, на виході . Для того, щоб перезаписати$HISTFILE з урахуванням поточної сесії по всій історії, прямо зараз , питання:

(bash)$  history -w

Звичайно, для предметів історії, які вже є на диску, альтернативою редагуванню історії за допомогою history -dкоманд та видачі history -wє редагування $HISTFILEтекстового редактора.


1
«Маніпулювання історії з вищезгаданими командами буде ще тільки додати інші нові деталі до $HISTFILE, на виході .» На насправді, це не зовсім вірно. Схоже, додаються лише нові елементи, які "стирчать" від початкової тривалості історії. Наприклад, якщо я видаляю 5 оригінальних елементів і додаю 15 нових, додаються лише останні 10 нових, тоді як я очікую, що всі 15 нових будуть додані. Я думаю, що це помилка, тому що я не бачу, як це завжди бажана функціональність.
Джеймс Хей

1
Я думаю, що баш враховує початкову довжину. Після закриття сесії він, ймовірно, додає елементи, кількість яких перевищує це значення. Якщо це значення зменшувалося кожного разу при видаленні елемента, число якого менше або дорівнює цьому значенню, воно буде працювати як очікувалося. ;-)
Джеймс Хей

15

Кілька прийомів:

Запобігайте збереженню конфіденційної інформації у файлі історії

Якщо ви ввели якийсь пароль в командному рядку, то зрозумівши, що всі команди записуються в журнал, ви можете:

  1. Примушуйте вийти з поточного сеансу без збереження історії:

     kill -9 $$

    Це скине всю поточну історію.

  2. Введіть ↑ (up arrow)сеанс відкритого bash, поки не відобразиться конфіденційна інформація, а потім використовуйте клавіші редагування рядків типу " Ctrl+" Wдля видалення конфіденційної інформації, а потім, ↓ (down arrow) поки не буде запропоновано новий порожній рядок, перед тим як набрати Enter.

Видаліть конфіденційну інформацію з файла історії

Якщо ви розумієте, що конфіденційна інформація вже зберігається, і ви хочете її видалити, але не всю вашу історію:

Проста sedкоманда може виконати цю роботу:

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

але, коли ви вводите це, ви створюєте інший рядок історії, що містить шаблон пошуку (конфіденційна інформація), який ви намагаєтесь видалити. Так ви могли:

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

Це буде працювати head -n1з введенням з терміналу. Виявиться, що ваш термінал підвішений (підказки не буде); просто введіть інформацію, яку потрібно видалити з файлу. Це хитрість, що дозволяє вам ввести команду (частину), не фактично вводячи її в командний рядок, тим самим зробивши її непридатною для включення до запису історії. Потім sedбуде використаний текст, який ви ввели, для пошуку .bash_history та видалення всіх рядків, що містять конфіденційну інформацію. Примітка: якщо ваш шаблон конфіденційної інформації містить косої риси, ви повинні уникати їх з косою косою рисою чи іншим чином змінити sedкоманду, щоб використовувати цей синтаксис, щоб вказати роздільник, який не відображається в шаблоні:

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

Іншим способом може бути видалення лише конфіденційної інформації, але зберігайте команди, які містять інформацію. Для цього ви можете просто замінити конфіденційну інформацію замість тексту на ваш вибір:

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

Видаліть конфіденційну інформацію з будь-якого файлу з конкретного дерева

Нарешті, щоб бути впевненим, що це не залишиться в іншому забутому файлі:

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

відобразить усі зацікавлені файли.

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

замінить усі події конфіденційної інформації у всіх файлах дерева дерев каталогів .. Примітка. Навіть якщо ця команда використовується xargs -0, вона не обробляє файли з новими рядками у своїх іменах.


11

Знайдіть рядок, який потрібно видалити, натискаючи, ↑ (up arrow)поки він не з’явиться, а потім натисніть Ctrl+ U. Це повинно видалити рядок.

Якщо ви використовуєте historyкоманду, ви можете бачити, що рядок було замінено зірочкою.


2
Насправді, я вважаю, що потрібно ввести курсор до рядка, натиснути Ctrl + U, а потім курсор вгору або вниз до іншого рядка (можливо, порожнього в нижній частині списку). Крім того, строго кажучи, рядок не було замінено зірочкою. Швидше, команда була стерта, а номер історії був доданий знаком a *.
G-Man

1
Це стає набагато потужнішим за допомогою Ctrl + R (зворотний поступовий пошук історії), тоді, наприклад, [Кінець], Ctrl + U
вересень

4

Якщо вам потрібно видалити кілька рядків одночасно, я зазвичай використовую це:

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

Якщо вам потрібно видалити останню команду, ви можете використовувати:

history -d $((HISTCMD-2))

2
Це виглядало так, як це спрацювало, але history | grep <string>все ще відображає всі рядки, які він стверджував, що видаляється ...
Брок Хенслі,

1
Це видалить неправильні рядки історії після видалення fisrt !!
mivk

1
Але, на щастя, він друкує лише неправильні команди видалення. Далі буде надруковано правильні команди видалення:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk

3

Якщо вам потрібно видалити діапазон рядків з історії, наступна функція bash може заощадити певний час:

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
}

Функцію слід зазвичай додавати до $HOME/.bashrc. Щоб використовувати функцію негайно, вам потрібно буде знову прочитати файл за допомогою запущеної оболонки ( . $HOME/.bashrc). Потім видалити, наприклад, команди 200-210 з історії:

$ histdel 200 210

(Примітка. Це питання належить до найпопулярніших результатів пошуку, якщо ви шукаєте для видалення діапазону команд з історії bash. Отже, хоч це вище, ніж те, що запитує, воно може бути корисним для деяких читачів.)


3
Альтернативні форми forвисловлювання: for n in $(seq "$2" "$1")стилістично віддані переваги деяким, і, якщо seqце не працює, спробуйте for ((n="$2"; n>="$1"; n--)).
Скотт

3
history | sed -i 59d

59 - номер рядка. Не може бути нічого солодшого за це :)


3

Просто спробуйте,

$ history

це відобразить ідентифікатор історії та команди, наприклад

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

використання,

$ history -d 211

Тут 211 - ідентифікатор історії. Тепер перевірте це за допомогою

$ history

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


2

Я знаю, що минуло давно, як на це питання було задано і відповіли, але я покажу вам свій спосіб очищення мого файлу історії та виходу з нього одночасно.

Я біжу : history -w && nano "${HISTFILE}" && history -c && exit

Це робиться просто:

  1. history -w : пише кешовану історію всередині "${HISTFILE}"
  2. nano "${HISTFILE}": дозвольте мені редагувати "${HISTFILE}"Ви можете використовувати сценарій sed або все, що хочете, щоб очистити свій"${HISTFILE}"
  3. history -c : очистити історію кешування, щоб ця остання команда не була додана.
  4. exit : вийдіть із допису кешованої історії ... але вона порожня;)

Після цієї команди ви вийдете із чистого файлу історії. Увійдіть, щоб перевірити свою історію;)

Я сподіваюся, що це комусь допоможе.


1

Ви також можете редагувати файл історії безпосередньо, наприклад, nano .bash_historyякщо ви перебуваєте в оболонці bash?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.