我想用一个非常强大的技巧来保存我输入的每条命令:
function zshaddhistory() {
COMMAND_STR=${1%%$'\n'}
[[ ( -z $COMMAND_STR ) || ( $COMMAND_STR =~ hist(ory)? ) || \
( $COMMAND_STR =~ ^l(s\|l\|a)?$ ) || \
( $COMMAND_STR =~ ^(d\|gd\|git\ diff\|glp\|gg)$ ) \
]] && return 1
# do not do anything on common commands
# do the needful
echo "$PWD; $COMMAND_STR; $TTY@$HOST@$(date +%s.%N)" >> ~/.zsh_enhanced_history
# rest is supposedly "default" zshaddhistory() (except it ain't)
print -Sr ${COMMAND_STR}
fc -p
}
要让它正常工作(例如使用 print -S
所以它不会搞砸 !$
等)是一件很困难的事,但它是现在主要为我工作。
但是,我注意到现在保存的内容存在一些细微的不一致,因为我正在构建一个 python 脚本,该脚本将保存的命令漂亮地打印在彩色列中。
举例说明:
% echo "\\"
\
现在 ~/.zsh_enhanced_history
现在包含:
/home/slu/util; echo "\"; /dev/pts/20@1376064693.136746657
因此,它将 echo "\\"
(产生输出 \
)保存为 echo "\"
(这不是格式良好的命令)。
类似地,命令 echo "\n"
以文字换行符保存,因此它将在历史文件中占用两行。事实上,正是这种行为导致我最初找到它,因为我的 python 正则表达式会为命令产生与该命令中有换行符一样多的失败解析。
我尝试更改它,以便将 printf "%q""$COMMAND_STR"
的输出保存为 $COMMAND_STR
,这似乎确实解决了换行问题,也许甚至反斜杠,但它使它转义空格和双引号,所以它也是错误的。
常规 ~/.zsh_history
文件不会遇到此问题,它包含与键入的命令完全相同的命令。
所以在我的 zshaddhistory
某处我没有进行正确的转换。也许我需要防止发生额外的 shell-string-eval。
需要 zsh 专家的帮助!!
最佳答案
This example从 zsh 邮件列表使用 print
。将它与您的功能结合起来可以得到:
zshaddhistory () {
# Print to the default history file with the newline stripped.
print -sr -- "${1%%$'\n'}"
# Ignore common commands.
COMMAND_STR=${1%%$'\n'}
[[ ( -z $COMMAND_STR ) || ( $COMMAND_STR =~ hist(ory)? ) || \
( $COMMAND_STR =~ ^l(s\|l\|a)?$ ) || \
( $COMMAND_STR =~ ^(d\|gd\|git\ diff\|glp\|gg)$ ) \
]] && return 1
# Switch history contexts
fc -p ~/.zsh_history_detail
# Push the current line into the current history context with newline stripped and user / time appended.
print -sr -- "${1%%$'\n'} ### ${PWD} $(date '+%Y-%m-%d %R')"
return 1
}
这似乎可以满足您的要求。我已经使用 echo "\\"
和 echo "\n"
进行了测试:
charizard% cat ~/.zsh_history_detail
cat: /Users/simont/.zsh_history_detail: No such file or directory
charizard% echo "\\"
\
charizard% cat ~/.zsh_history_detail
: 1376117319:0;echo "\\" ### /Users/simont 2013-08-10 16:18
charizard% cat "\n" # This was an oopsie
cat: \n: No such file or directory
charizard% echo "\n"
charizard% echo "\\"
\
charizard% cat ~/.zsh_history_detail
: 1376117319:0;echo "\\" ### /Users/simont 2013-08-10 16:18
: 1376117334:0;cat "\n" ### /Users/simont 2013-08-10 16:18
: 1376117339:0;echo "\n" ### /Users/simont 2013-08-10 16:18
: 1376117343:0;echo "\\" ### /Users/simont 2013-08-10 16:19
我不明白你的意思:
but it makes it escape spaces and double-quotes, so it is also wrong
所以我无法对此进行测试。
关于linux - 正确的 zsh shell 命令转义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18151273/