在试图让我的命令.zshrc
更整洁时,我偶然发现了以下问题:“如何运行另一个命令的输出?”。虽然我确信这是一个简单的问题,但我只是不明白我做错了什么。
我想添加点完成到我的配置。为此,我需要添加$ pip completion --zsh
to的输出.zshrc
:
$ pip completion --zsh
# pip zsh completion start
function _pip_completion {
local words cword
read -Ac words
read -cn cword
reply=( $( COMP_WORDS="$words[*]" \
COMP_CWORD=$(( cword-1 )) \
PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null ))
}
compctl -K _pip_completion pip
# pip zsh completion end
现在,上面的线条看起来不太好。相反,我尝试将以下行添加到.zshrc
:
eval $(pip completion --zshrc)
但是,pip 补全并未“安装”(与我在 中添加行本身时相反.zshrc
),但我也没有收到任何错误。
我有一种感觉,zsh
没有#
正确评估线路,但我不确定如何测试它。当我运行时$ eval $(pip completion --zshrc)
没有弹出错误。
我哪里错了?是否有类似的替代方法来评估$ pip completion --zsh
my的输出.zshrc
?
答案1
你需要跑
eval "$(pip completion --zsh)"
比较这两个命令的输出:
echo $(pip completion --zsh)
echo "$(pip completion --zsh)"
在 zsh 中,$VARIABLE
意思是“取值,VARIABLE
除非它为空”。但$(command)
意味着“获取输出command
并在空白处将其分解为单词”。因此,在 中eval $(pip completion --zsh)
,所有空白序列(包括换行符)都被视为单词分隔符。然后eval
将其所有参数放在一起,每个参数之间留一个空格。但空格并不等同于换行符,eval
执行的代码只是一长串注释行。
这是一个子集为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?:在 zsh 中,与其他类似 sh 的 shell 不同,分词仅发生在命令替换上,而不发生在变量替换上(除了在限制形式中,其中由变量替换产生的空字被消除),并且结果上不会自动发生通配符的扩张。在 zsh 中,您确实需要在命令替换周围使用双引号,并且在变量替换周围(当它可能导致空单词时)。