Ответ 1
Вы пытались напрямую редактировать файл истории:
~/.bash_history
Команды следуют за
511 clear
512 history
513 history -d 505
514 history
515 history -d 507 510 513
516 history
517 history -d 509
518 history
519 history -d 511
520 history
Я могу удалить одиночный файл history -d 511
, но как удалить последние 10 команд и между 10 командами истории с помощью одной команды в оболочке?
Можем ли мы написать bash script и выполнить для удаления истории?
Вы пытались напрямую редактировать файл истории:
~/.bash_history
Мой ответ основан на предыдущих ответах, но с добавлением обратной последовательности, чтобы элементы истории удалялись из самых последних в наименее недавние.
Получить текущую историю (отрегулируйте количество строк, которые вы хотите видеть):
history | tail -n 10
Это дает мне что-то вроде
1003 25-04-2016 17:54:52 echo "Command 1"
1004 25-04-2016 17:54:54 echo "Command 2"
1005 25-04-2016 17:54:57 echo "Command 3"
1006 25-04-2016 17:54:59 echo "Command 4"
1007 25-04-2016 17:55:01 echo "Command 5"
1008 25-04-2016 17:55:03 echo "Command 6"
1009 25-04-2016 17:55:07 echo "Command 7"
1010 25-04-2016 17:55:09 echo "Command 8"
1011 25-04-2016 17:55:11 echo "Command 9"
1012 25-04-2016 17:55:14 echo "Command 10"
Выберите начальную и конечную позиции для элементов, которые вы хотите удалить. Я собираюсь удалить записи от 1006 до 1008.
for h in $(seq 1006 1008 | tac); do history -d $h; done
Это сгенерирует history -d
команды history -d
для 1008, затем 1007, затем 1006.
Если я также хотел удалить команду удаления истории, то это немного сложнее, потому что вам нужно знать текущую максимальную запись истории.
Вы можете получить это с (может быть лучший способ):
history 1 | awk '{print $1}'
Собрав все вместе, вы можете использовать это для удаления диапазона, а также для удаления команды удаления истории:
for h in $(seq 1006 1008 | tac); do history -d $h; done; history -d $(history 1 | awk '{print $1}')
Оберните все это в функцию для добавления в ваш ~/.bashrc
:
histdel(){
for h in $(seq $1 $2 | tac); do
history -d $h
done
history -d $(history 1 | awk '{print $1}')
}
Пример удаления команд 4, 5 и 6 (1049-1051) и сокрытия улик:
[18:21:02 [email protected] ~]$ history 11
1046 25-04-2016 18:20:47 echo "Command 1"
1047 25-04-2016 18:20:48 echo "Command 2"
1048 25-04-2016 18:20:50 echo "Command 3"
1049 25-04-2016 18:20:51 echo "Command 4"
1050 25-04-2016 18:20:53 echo "Command 5"
1051 25-04-2016 18:20:54 echo "Command 6"
1052 25-04-2016 18:20:56 echo "Command 7"
1053 25-04-2016 18:20:57 echo "Command 8"
1054 25-04-2016 18:21:00 echo "Command 9"
1055 25-04-2016 18:21:02 echo "Command 10"
1056 25-04-2016 18:21:07 history 11
[18:21:07 [email protected] ~]$ histdel 1049 1051
[18:21:23 [email protected] ~]$ history 8
1046 25-04-2016 18:20:47 echo "Command 1"
1047 25-04-2016 18:20:48 echo "Command 2"
1048 25-04-2016 18:20:50 echo "Command 3"
1049 25-04-2016 18:20:56 echo "Command 7"
1050 25-04-2016 18:20:57 echo "Command 8"
1051 25-04-2016 18:21:00 echo "Command 9"
1052 25-04-2016 18:21:02 echo "Command 10"
1053 25-04-2016 18:21:07 history 11
На самом деле вопрос заключался в том, чтобы удалить последние 10 команд из истории, поэтому, если вы хотите сэкономить немного усилий, вы можете использовать другую функцию для вызова функции histdel
которая выполняет вычисления за вас.
histdeln(){
# Get the current history number
n=$(history 1 | awk '{print $1}')
# Call histdel with the appropriate range
histdel $(( $n - $1 )) $(( $n - 1 ))
}
Эта функция принимает 1 аргумент, количество предыдущих элементов истории, которые нужно удалить. Поэтому, чтобы удалить последние 10 команд из истории, просто используйте histdeln 10
.
for x in `seq $1 $2`
do
history -d $1
done
Сначала введите: history
и запишите последовательность номеров строк, которые вы хотите удалить.
Чтобы очистить строки от let say line 1800 to 1815, напишите в терминале следующее:
$ for line in $(seq 1800 1815) ; do history -d 1800; done
Если вы хотите удалить историю для команды удаления, добавьте +1 для 1815 = 1816 и историю для этой последовательности + команда удаления будет удалена.
Например:
$ for line in $(seq 1800 1816) ; do history -d 1800; done
Изменено сжатие итераторов, хороший вызов. Кроме того, вызовите эту функцию с помощью обратного итератора.
Возможно, вы можете сделать что-то вроде этого:
#!/bin/bash
HISTFILE=~/.bash_history # if you are running it in a
# non interactive shell history would not work else
set -o history
for i in `seq $1 $2`;
do
history -d $i
done
history -w
Где вы будете вызывать так:
./nameOfYourScript 563 514
Примечание. Я не проверял ошибки для границ. Я оставлю это как упражнение для читателя.
см. также этот вопрос
Объединение ответов сверху:
history -w
vi ~/.bash_history
history -r
Может быть, это будет полезно для кого-то.
Когда вы входите в систему для любого пользователя любой истории консоли/терминала вашего текущего сеанса, существует только в некотором "буфере", который сбрасывается в ~/.bash_history при выходе из системы.
Итак, чтобы хранить вещи в секрете, вы можете просто: history -r && exit
и вы выйдете из системы со всей вашей сессией (и только), очищенная история;)
history -c очистит все истории.
Я использую этот скрипт, чтобы удалить последние 10 команд в истории:
pos=$HISTCMD; start=$(( $pos-11 )); end=$(( $pos-1 )); for i in $(eval echo "{${start}..${end}}"); do history -d $start; done
Он использует $HISTCMD
среды $HISTCMD
для получения индекса истории и использует его для удаления последних 10 записей в history
.
Я использовал комбинацию решений в этой теме, чтобы стереть след в истории команд. Сначала я проверил, где хранится история команд:
echo $HISTFILE
Я редактировал историю с:
vi <pathToFile>
После этого я очищаю буфер истории текущей сессии:
history -r && exit
В следующий раз, когда вы войдете в этот сеанс, последняя команда, которую вы увидите в истории команд, является последней, которую вы оставили в pathToFile.
С Bash 5 вы теперь можете делать диапазон... Ура!
history -d 511-520
или считая в обратном направлении 10:
history -d -10--1
Отрывок из страницы Bash 5 Man:
"История"
Опции, если они есть, имеют следующие значения:
'-d OFFSET' Удалить запись истории в положении OFFSET. Если значение OFFSET положительное, его следует указать так, как оно отображается при отображении истории. Если значение OFFSET отрицательное, оно интерпретируется как относительное относительно единицы, превышающей последнюю позицию истории, поэтому отрицательные индексы отсчитываются с конца истории, а индекс "-1" относится к текущей "истории -d". команда.
'-d START-END' Удалить записи истории между позициями START и END включительно. Положительные и отрицательные значения для START и END интерпретируются, как описано выше.
Вот мое решение для Bash 4:
delHistory () {
count=$(( ${2:-$1} - $1 ))
while [[ $count -ge 0 ]] ; do
history -d "$start"
((count--))
done
}
delHistory 511 520
for h in $(seq $(history | tail -1 | awk '{print $1-N}') $(history | tail -1 | awk '{print $1}') | tac); do history -d $h; done; history -d $(history | tail -1 | awk '{print $1}')
Если вы хотите удалить 10 строк, просто измените значение N на 10.
Простая функция может убить всех по числу (хотя это barfs на ошибках)
kill_hist() {
for i in $(echo [email protected] | sed -e 's/ /\n/g;' | sort -rn | sed -e 's/\n/ /;')
do
history -d $i;
done
}
kill_hist `seq 511 520`
# or kill a few ranges
kill_hist `seq 1001 1010` `seq 1200 1201`
Попробуйте следующее:
for i in {511..520}; do history -d $i; echo "history -d $i"; done
удалить последние 10 записей (на основе вашего примера):
history -d 511 520