我有一个函数,我在zshenv中声明为自动加载。当我从zsh提示符或zsh脚本调用它时,它工作正常。但是当我尝试从Ruby脚本(使用`my_zsh_autoloaded_function`
)调用它时,它失败了。我知道Ruby正在使用zsh,我知道zshenv正在被采购。一种解决方法是`zsh -c "my_zsh_autoloaded_function"`
。有没有办法让Ruby直接访问?
答案 0 :(得分:6)
你做不到。这不是Unix命令执行的工作原理。
Zsh基本上是REPL,就像irb
一样。
为了让Zsh执行内部命令,它必须执行以下操作之一:
-c
开关执行命令,或.. 当您执行`zsh_function`
时,不会满足这些先决条件。
但您实际上已经使用zsh -c
找到了(正确的)解决方案之一。
但您感到困惑,因为您正在查看$SHELL
并认为您正在zsh
下运行。 $SHELL
不是运行哪个shell的可靠指标:
> zsh
> echo $SHELL
/usr/bin/zsh
> sh
$ echo $SHELL
/usr/bin/zsh
$ bash
$ echo $SHELL
/usr/bin/zsh
$ SHELL=foo
$ bash
$ echo $SHELL
foo
因此,只需将SHELL
从原始环境复制到您正在生成的任何新环境或shell中。
现在,最后一块拼图隐藏在Ruby源代码中,也隐藏在Kernel.exec的帮助文件中:
标准shell在类Unix系统上始终表示“/ bin / sh”,与ENV [“RUBYSHELL”](或Windows NT系列上的ENV [“COMSPEC”]相同),类似。
所以不,Unix上的Kernel.system
或反引号不会运行zsh
。它总是直接运行程序(例如/bin/ls
)或运行sh -c
以防bash命令或需要任何其他shell处理的命令(如ls *
)。
也很容易检查:
> zsh
> irb
> puts `ps xf; echo hello`
PID TTY STAT TIME COMMAND
24122 ? S 0:00 sshd: casper@pts/7
24127 pts/7 Ss 0:00 \_ -zsh
24686 pts/7 S 0:00 \_ zsh
24706 pts/7 Sl+ 0:00 \_ irb
24710 pts/7 S+ 0:00 \_ sh -c ps xf; echo hello
24712 pts/7 R+ 0:00 \_ ps xf
<强>解决方案强>
使用zsh -c
运行,就像你一样,或者使用命令创建一个单独的Zsh shell脚本并运行它。