如何从ruby脚本访问自动加载的zsh函数?
我有一个在zshenv中声明为自动加载的函数。当我从zsh提示符或zsh脚本调用它时,它工作正常。但是当我尝试从Ruby脚本调用它时(使用如何从ruby脚本访问自动加载的zsh函数?,ruby,zsh,Ruby,Zsh,我有一个在zshenv中声明为自动加载的函数。当我从zsh提示符或zsh脚本调用它时,它工作正常。但是当我尝试从Ruby脚本调用它时(使用`my_zsh_autoloaded_function`),它失败了。我知道Ruby正在使用zsh,我也知道zshenv正在采购中。一种解决方法是执行`zsh-c“my_zsh_autoloaded_函数”`。有什么方法可以让Ruby直接访问吗?你不能。这不是Unix命令执行的工作方式 Zsh本质上是一个类似于irb 为了让Zsh执行内部命令,它必须执行以下操
`my_zsh_autoloaded_function`
),它失败了。我知道Ruby正在使用zsh,我也知道zshenv正在采购中。一种解决方法是执行`zsh-c“my_zsh_autoloaded_函数”`
。有什么方法可以让Ruby直接访问吗?你不能。这不是Unix命令执行的工作方式
Zsh本质上是一个类似于irb
为了让Zsh执行内部命令,它必须执行以下操作之一:
- 从REPL循环(STDIN)读取命令
- 使用
开关执行命令,或-c
- 从Zsh shell脚本文件运行该命令
`zsh\u函数`
,这些先决条件都不会得到满足
但实际上,您已经通过使用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源代码中,也隐藏在以下帮助文件中:
在类Unix系统上,标准shell始终表示“/bin/sh”,与ENV[“RUBYSHELL”](或Windows NT系列上的ENV[“COMSPEC”])和类似名称相同
因此,在Unix上,Kernel.system
或backticks将不会运行zsh
。它总是直接运行程序(例如/bin/ls
),或者在bash命令或需要任何其他shell处理的命令(如ls*
)的情况下运行sh-c
)
也很容易检查:
> 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脚本并运行它。您如何知道backticks正在执行zsh
?@muistooshort``putsecho$shell
`prints/usr/local/bin/zsh
;我还可以访问zshenv
中定义的backticks中的环境变量,感谢您的全面响应——非常有教育意义。不过,我确实发现有一件事不清楚——如果Ruby运行的是zsh而不是/bin/sh,那么在backticks中调用该函数就行了吗?您的回答的第一部分表明,除了使用backticks调用的shell不是zsh这一事实之外,还有一些原因表明这不起作用,但我不清楚这是什么原因。换句话说,/bin/sh是否可以通过backticks执行“内部命令”(不太确定什么是内部命令)。我想我可能没有用最好的方式来表达。你是对的。正如您所看到的,Ruby正在运行sh
,并且带有-c
标志。因此,如果Ruby使用zsh
而不是sh
,那么它是可以工作的,因为在这种情况下,-c
条件将得到满足。答案很简单。这比实际情况要复杂一点,因为Ruby有一些内部逻辑来尝试检测哪些backtick参数是真正的内部sh
命令,哪些不是(这样它就知道什么时候触发-c
),但理论上是可以的。啊,我明白了,现在很有意义了。Ruby解析backticks输入并通过sh-c
路由某些命令,在其他情况下直接调用程序。再次感谢@西恩马克西是正确的。您可以在此处查看相关代码: