我想知道如果我输入该命令的子字符串,该命令会是什么样子。我对结果不感兴趣,而是对历史的扩展感兴趣。
这样做的目的是以交互的方式展示 zsh 中的扩展是如何工作的。
例如,假设我想说明 zsh 历史修饰符的用法:
mv /Volumes/hdd1/path/to/a/file.foo !#$:r:s/foo/bar/ # moves and renames at the same time
....................................0123456789abcdef
(上面的行是本题中引用子字符串的规则)
有些子字符串有效,有些则无效。
我希望对于以 [0..f] 结尾的每个子字符串执行历史扩展,就像我TAB在 [0..f] 中的每个字符之后键入一样。
答案1
我不认为你可以触发历史扩展并从 zsh 中取回结果。
这是使用的概念验证zpty
模块要与较差的 zsh 进程交互,请让它扩展历史字符串并研究结果(可能是报告错误或执行命令)。将每次扩展尝试之前所需的初始历史记录放入名为 的文件中prior_history
。
#!/usr/bin/zsh
setopt extended_glob
zmodload zsh/zpty
zpty -b inferior_zsh 'PS1=%% PS2=\> TERM=dumb strace -eread,write -o zsh.strace zsh -f'
zpty -r inferior_zsh out $'*\r%'
zpty -w inferior_zsh 'stty -echo'
zpty -r inferior_zsh out $'*\r%'
start='mv /Volumes/hdd1/path/to/a/file.foo'
history_string='!#$:r:s/foo/bar/'
for ((i=1; i <= $#history_string; i++)) {
zpty -w inferior_zsh "fc -R prior_history"
zpty -r inferior_zsh out $'*\r%'
zpty -w inferior_zsh "print -r expansion: ${(q)start} ${history_string[1,$i]}"
zpty -r inferior_zsh out $'*\r[%>]'
out=${${out#*$'\r\r\n'}%$'\r\n'% ##$'\r\r%'}
print -r "$i ${(qqqq)out}"
}