如何在zsh中获取当前执行命令全称以用作邮件主题
zsh获取当前执行命令行的两种可行方案
方案1:无需修改配置,直接在命令行使用
利用zsh历史扩展的!#语法加:q修饰符即可实现和tcsh一致的效果,!#代表当前正在输入的完整命令行,:q修饰符会自动处理内容转义,避免引号不匹配报错:
# 测试验证 printf "%s\n" !#:q # 输出与你输入的命令完全一致 # 发邮件场景用法 ~/script.sh 2>&1 | mail -s !#:q user@example.org
如果不习惯历史扩展语法,也可以用fc命令手动提前刷新历史后读取:
fc -A; ~/script.sh 2>&1 | mail -s "$(fc -ln -1 | sed '1s/^[ \t]*//')" user@example.org
这里fc -A的作用是提前把当前正在执行的命令写入历史列表,就不会出现读取滞后一条的问题,无需额外调用tr处理空格。
方案2:配置一次全局可用
如果经常需要用到当前命令行,可直接在~/.zshrc中添加preexec钩子,zsh会在命令执行前自动将完整命令行存入你指定的变量:
# 加到~/.zshrc末尾 preexec() { export CURRENT_CMD="$1" }
配置重载后,任何场景下直接引用$CURRENT_CMD变量即可:
~/script.sh 2>&1 | mail -s "$CURRENT_CMD" user@example.org
该方案无需额外处理文本,不会出现历史重复、内容错位的问题,长期使用更方便。
之前方案失效原因说明
- history命令滞后一条:zsh默认仅在命令执行完成后才将其追加到历史列表,所以命令执行过程中调用
history -1读取到的是上一条已经执行完成的命令。 - !#语法报错:直接将
!#放在双引号中会触发引号解析冲突,添加:q修饰符后zsh会自动对内容做转义处理,即可正常使用。
内容的提问来源于stack exchange,提问作者cnst
相关产品推荐
相关产品推荐

