linux - 正确的 zsh shell 命令转义

标签 linux macos shell unix zsh

我想用一个非常强大的技巧来保存我输入的每条命令:

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/

相关文章:

java - Eclipse 释放堆回到系统

linux - 如何从内核模块中找到动态链接/加载库的 PHDR?

java - Pyspark:异常:Java 网关进程在向驱动程序发送其端口号之前退出

bash - 如何在 bash shell 中将一个字符串拆分为多个变量?

c - 为什么 pthread 中需要线程特定数据?

linux - SSH 作为用户允许在 Linux 中进行临时 root 访问

java - Spring Boot 无法监听端口

macos - 在 macOS 上安装没有完整 Postgres 的 psql 的正确方法?

php - 使用 inotify 通知新文件

linux - 在 C shell 中计算数字的总和