不能發表評論,但(這超出了一個簡單的更正),所以我會添加這個答案。
This correction到the accepted answer完全不是那麼回事的時候,例如,最後一個命令了相當多的時間來執行 - 你會得到流浪數字和你的命令;
,像這樣:
2017-07-22 19:02:42 | 3;micro ~/.zshrc && . ~/.zshrc
這可以通過在command_part
與稍長gawk
,這也避免了我們一個管道更換sed -re '1s/.{15}//'
固定:
local command_part="$(gawk "
NR == $line_num_last {
pivot = match(\$0, \";\");
print substr(\$0, pivot+1);
}
NR > $line_num_last {
print;
}" ~/.zsh_history)"
它也有問題時deali使用多行命令,其中一行以:
開頭。這可以(大部分)通過用grep -anE '^: [0-9]{10}:[0-9]*?;' ~/.zsh_history
代替line_num_last
中的grep -ane '^:' ~/.zsh_history
來解決 - 我說主要是因爲一個命令可能包含一個匹配該表達式的字符串。再說了,
% naughty "multiline
> command
> ::123;but a command I'm not
> "
這將導致~/.persistent_history
一個慘敗紀錄。
爲了解決這個問題,我們需要反過來,檢查以前的redord是否有結束\
(可能還有其他的條件,但我不是這樣的歷史格式熟悉卻又),如果是這樣嘗試之前的比賽。
_get_line_num_last() {
local attempts=0
local line=0
while true; do
# Greps the last two lines that can be considered history records
local lines="$(grep -anE '^: [0-9]{10}:[0-9]*?;' ~/.zsh_history | \
tail -n $((2 + attempts)) | head -2)"
local previous_line="$(echo "$lines" | head -1)"
# Gets the line number of the line being tested
local line_attempt=$(echo "$lines" | tail -1 | cut -d':' -f1 | tr -d '\n')
# If the previous (possible) history records ends with `\`, then the
# _current_ one is part of a multiline command; try again.
# Probably. Unless it was in turn in the middle of a multi-line
# command. And that's why the last line should be saved.
if [[ $line_attempt -ne $HISTORY_LAST_LINE ]] && \
[[ $previous_line == *"\\" ]] && [[ $attempts -eq 0 ]];
then
((attempts+=1))
else
line=$line_attempt
break
fi
done
echo "$line"
}
precmd() {
local line_num_last="$(_get_line_num_last)"
local date_part="$(gawk "NR == $line_num_last {print;}" ~/.zsh_history | cut -c 3-12)"
local fmt_date="$(date -d @${date_part} +'%Y-%m-%d %H:%M:%S')"
# I use awk itself to split the _first_ line only at the first `;`
local command_part="$(gawk "
NR == $line_num_last {
pivot = match(\$0, \";\");
print substr(\$0, pivot+1);
}
NR > $line_num_last {
print;
}" ~/.zsh_history)"
if [ "$command_part" != "$PERSISTENT_HISTORY_LAST" ]
then
echo "${fmt_date} | ${command_part}" >> ~/.persistent_history
export PERSISTENT_HISTORY_LAST="$command_part"
export HISTORY_LAST_LINE=$((1 + $(wc -l < ~/.zsh_history)))
fi
}
[這](http://superuser.com/questions/735660/whats-the-zsh-equivalent-of-bashs-prompt-command)應與替換'PROMPT_COMMAND'幫助。替換[[''用法應該可以用'grep -o'或'cut'或類似的方法來實現,但是取決於zsh中'history'的確切輸出。 –
@EtanReisner非常感謝!對於'PROMPT_COMMAND',鏈接應該是有幫助的。對於''[''部分,我剛剛用'history'命令發現,bash會在最後一行給出最新的一個(在這種情況下,它是'history')。但是在Zsh下,'history'命令不會返回最新的命令,它會在最後一行返回'history'之前使用的命令。有任何想法嗎? :-) – astroboylrx
那麼,我沒有理由重新發明輪子。只需設置'HISTFILE'並將'HISTSIZE'和'SAVEHIST'設置爲一個非常大的尺寸(我的尺寸是100,000),並且我沒有理由讓它們變大,因爲我在iTerm2中記錄了所有終端會話 - 這就是所有命令+輸出,在提示中時間縮短到秒)。默認的歷史記錄格式具有關聯的POSIX時間戳,由於您沒有tzinfo,所以它比您的更準確。 – 4ae1e1