[英]ZSH: execute function in a script file
我有一个~/scripts/git-workflow.sh
文件,看起来像:
#!/bin/zsh
gp() {
local cmd="git pull"
echo "=> $cmd"
$cmd
}
它基本上是一个更好的别名,它会在我使用别名时打印出命令,这样我就不会随着时间的推移忘记实际的命令。
在我的.zshrc
文件中,我提供source ~/scripts/git-workflow.sh
。
在我的 zsh 提示符下,当我执行$ gp
它似乎运行了该函数但失败了。
$ gp
=> git pull
gp:5: command not found: git pull
但是,如果我直接在命令行上执行$ git pull
,它运行得很好。
$ git pull
Already up to date.
当我使用bash
,这工作正常,但我最近切换到zsh
(感谢 Apple 将其用作默认设置)并且在执行我的脚本时遇到问题。
是否需要将我的函数放入某些特殊格式,或者我需要添加到 zsh 中以使其工作?
zsh
默认不对参数扩展执行分词,因此git
和pull
在所需命令中不是两个单独的词。 虽然您可以在特定参数扩展上启用它,但更好的方法是仅使用数组。
gp () {
local cmd=(git pull)
echo "=> ${cmd[*]}"
"${cmd[@]}"
}
如果要执行存储在变量中的命令,还可以尝试使用 (z) 标志${(z)cmd}
:
z:使用shell解析将扩展结果拆分为单词以查找单词,即考虑值中的任何引用。 ( 参数扩展标志)
在zsh中,参数(变量)扩展默认不进行分词。
$ x="hello world 'a b c'"
# check the number of arguments with an anonymous function:
# $x is regarded as one argument as a whole
$ () { echo ${#} args; echo ${(F)@} } $x
1 args
hello world 'a b c'
${(z)x}
执行“词法分词”,它理解值中的引号:
$ () { echo ${#} args; echo ${(F)@} } ${(z)x}
3 args
hello
world
'a b c'
${=x}
基于IFS
执行“简单分词”; 单词以空格分隔:
$ () { echo ${#} args; echo ${(F)@} } ${=x}
5 args
hello
world
'a
b
c'
您的命令行似乎运行 bash,但您正在采购的文件是 zsh。 就好像你在 C 中#include
一个 C++-include 文件一样。 这行不通。
在 bash 中,分词发生在$cmd
展开后,导致命令
git pull
在 Zsh 中,扩展后不会发生分词。 因此,该命令被理解为
'git pull'
在您的 Zsh 函数中,您必须编写
${=cmd}
然后这将执行git pull
,但当然在 bash 下看到时它不再有效。 我建议你下定决心:你想让它在 bash 下工作,还是在 Zsh 下工作?
如果您同时使用两个 shell - 例如我正在这样做 - 为两个 shell 编写单独的实现,除非在 bash 和 Zsh 足够相似以至于单个实现就足够的情况下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.