개행이 포함된 여러 줄 기록 항목을 저장하도록 Bash를 구성했습니다.
shopt -s cmdhist lithist
export HISTTIMEFORMAT='%F %T '
셸을 종료하면 내 기록에 ~/.bash_history
항목을 구분하는 타임스탬프가 추가됩니다. 예를 들면 다음과 같습니다.
#1501293767
foo() {
echo foo
}
#1501293785
ls
HISTIGNORE
일부 명령을 필터링하도록 설정해 보았습니다 .
HISTIGNORE='ls[ ]*:man[ ]*:cat[ ]*'
그러나 곧 나는 현재 세션의 (메모리 내) 기록에 모든 것을 포함하는 것을 선호한다는 것을 깨달았고, 향후 세션을 위해 디스크에 기록되는 내용만 필터링하고 싶습니다.
~/.bash_logout
이 필터 기능을 활용하고 싶습니다 .이것들 답변몇 가지 관련 질문).
여러 줄 항목을 사용하면 필터링이 좀 더 복잡해집니다. 타임스탬프 뒤의 첫 번째 줄이 무시할 수 있는 패턴 중 하나와 일치하는 항목을 식별하고 타임스탬프를 포함한 전체 항목을 제외해야 합니다.
awk를 사용하여 이를 수행하는 방법을 알아냈지만 awk 실력이 그다지 좋지 않아서 더 좋은 방법이 있는지 궁금합니다.
filter_history() {
tmpfile=$(mktemp)
history -w $tmpfile
awk '/^#[[:digit:]]{10}$/ { timestamp=$0; ignore=0; next }
length(timestamp) > 0 && /^(ls|man|cat)([^[:alnum:]]|$)/ { timestamp=""; ignore=1 ; next }
length(timestamp) > 0 { print timestamp; timestamp=""; print; next }
ignore == 0 { print }' \
$tmpfile >> $HISTFILE && rm $tmpfile
}
편집하다: 사실 여러 줄 항목을 필터링하고 싶은 상황은 생각나지 않습니다. 예를 들어, 로 시작하더라도 ls
여러 줄에 걸쳐 있다면 아마도 흥미롭고 기억할 가치가 있는 일을 하고 있을 것입니다.
답변1
첫 번째 줄이 "무시" 패턴과 일치하더라도 여러 줄 항목을 유지해야 한다는 요구 사항으로 인해 약간의 복잡성이 추가됩니다. 나는 HISTFILE이 디스크에 기록된 후 이를 필터링하기 위해 Awk에 유한 상태 머신을 작성하게 되었습니다(기록되기 전에 필터링을 트리거하는 방법을 찾을 수 없었습니다).
~/.bashrc:
# if shell is interactive, filter history upon exit
if [[ $- == *i* ]]; then
trap '$HOME/.bash_history_filter >/dev/null 2>&1 &' EXIT
fi
~/.bash_history_filter:
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT
filter_script="$HOME/.bash_history_filter.awk"
persisted_history="${HISTFILE:-$HOME/.bash_history}"
if [[ -r "$filter_script" && -r "$persisted_history" ]]; then
awk -f "$filter_script" "$persisted_history" > "$tmpfile"
mv "$tmpfile" "$persisted_history"
fi
~/.bash_history_filter.awk:
/^#[[:digit:]]{10}$/ {
timestamp = $0
histentry = ""
next
}
$1 ~ /^(ls?|man|cat)$/ {
if (! timestamp) {
print
} else {
histentry = $0
}
next
}
timestamp {
print timestamp
timestamp = ""
}
histentry {
print histentry
histentry = ""
}
{ print }
일부 관련 게시물(여기그리고여기) 이것이 sed를 사용하여 수행될 수도 있다고 의심됩니다. 아직 알아보진 못했지만 비교해서 어떤지 알고 싶습니다.
답변2
완전성을 위해 bash 기록을 처리하는 방법은 다음과 같습니다! (필터 및 백업)
필터링 여부에 관계없이 HISTFILE은 자신의 이력을 걱정하는 사람들에게는 충분하지 않으며 큰 HISTFILE을 사용하는 것도 권장되지 않으므로 이력을 다른 곳에 저장해야 할 때가 분명히 올 것입니다!
function shellHist () #find old hist
{
if [[ -f ${HISTFILE}.${1} ]]; then
cat ${HISTFILE}.${1};
else
grep -h "${@:-.}" ${HISTFILE}.*;
fi
}
function shellHistBackup ()
{
[[ -n ${HISTFILE} ]] || return;
# pidKill0 && return; # do nothing if the job is actually running elsewhere
{
while read histLine; do
if ! grep -q "^${histLine}$" ${HISTFILE}.${histLine%% *} 2> /dev/null; then
echo "${histLine}" >> ${HISTFILE}.${histLine%% *};
fi;
done < ${HISTFILE}
for fltr in ls cat any ; do
rm ${HISTFILE}.${fltr}
done
} & # pidLog # related to pidKill0
}
"trap shellExit EXIT"에 shellHistBackup을 포함합니다.
이것이 누군가에게 유용하길 바랍니다!