Zsh preexec提取含空格命令最后参数及文件验证问题求助
解决Zsh preexec钩子中提取带空格文件名的问题
你的问题出在提取的候选文件名包含了Shell转义符\,但实际磁盘上的文件名是没有这个反斜杠的——比如你执行ls -l fred\ bill.txt时,Shell会把fred\ bill.txt解析成真实文件名fred bill.txt,但你的代码提取到的是带反斜杠的fred\ bill.txt,自然无法通过-f文件存在性检查。
不要用手动字符串截取处理命令参数,Zsh内置了专门的命令解析功能,能完美处理转义、引号等复杂情况,直接用它来拆分命令为参数数组即可:
fre_preexec () { local tmpcmd="$1" # 用(z)标志按照Zsh语法解析命令字符串,生成参数数组 local -a cmd_parts=(${(@z)tmpcmd}) # 取数组最后一个元素作为候选文件名 local cand_fname="${cmd_parts[-1]}" if [ -f "$cand_fname" ]; then fre --add "$cand_fname" fi }
为什么这个方案有效:
${(@z)tmpcmd}会自动处理命令中的转义符、单双引号:- 输入
ls -l fred\ bill.txt时,解析出的数组是(ls -l "fred bill.txt") - 输入
ls "my document.pdf"时,解析出的数组是(ls "my document.pdf")
- 输入
- 提取到的
cand_fname是真实的文件名,不带任何Shell解析用的转义或引号,直接用-f检查就能正确判断文件是否存在。
内容的提问来源于stack exchange,提问作者Jeff Templon
相关产品推荐
相关产品推荐

