繁体   English   中英

ZSH:在脚本文件中执行函数

[英]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默认不对参数扩展执行分词,因此gitpull在所需命令中不是两个单独的词。 虽然您可以在特定参数扩展上启用它,但更好的方法是仅使用数组。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM