ruby - 如何从 ruby​​ 脚本访问自动加载的 zsh 函数?

标签 ruby zsh

我有一个函数在我的 zshenv 中声明为自动加载。当我从 zsh 提示符或 zsh 脚本调用它时,它工作正常。但是当我尝试从 Ruby 脚本调用它时(使用 `my_zsh_autoloaded_function`),它失败了。我知道 Ruby 正在使用 zsh,而且我知道正在采购 zshenv。一种解决方法是执行 `zsh -c "my_zsh_autoloaded_function"`。有没有办法让 Ruby 直接访问?

最佳答案

你不能。这不是 Unix 命令执行的方式。

Zsh 本质上是一个 REPL就像 irb 一样。

为了让 Zsh 执行内部命令,它必须执行以下操作之一:

  • 从 REPL 循环 (STDIN) 中读取命令
  • 使用-c 开关执行命令,或者..
  • 从 Zsh shell 脚本文件运行命令

当您只是执行 `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 中。

现在,最后一 block 拼图隐藏在 Ruby 源代码中,也隐藏在 Kernel.exec 的帮助文件中。 :

The standard shell always means "/bin/sh" on Unix-like systems, same as ENV["RUBYSHELL"] (or ENV["COMSPEC"] on Windows NT series), and similar.

所以不,Kernel.system 或 Unix 上的反引号不会运行 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 脚本并运行它。

关于ruby - 如何从 ruby​​ 脚本访问自动加载的 zsh 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17264381/

相关文章:

ruby-on-rails - 你如何从 Rails 中的 View 调用方法?

ruby-on-rails - Ruby 2.7.2 使用 2.7.0 库

ruby-on-rails - 关于这个 Rails 关联案例中的 "<<"运算符

ruby - 如何在 LIKE 与 Datamapper 之间建立 OR 条件?

linux - 如何记录所有终端 session 并在关闭窗口后正确退出

flutter - xcrun : error: invalid active developer path, problem after zsh update for flutter

ruby - 意外的 $end ,期待 kEND

linux - zsh 下划线常用补全前缀

zsh - zsh别名->功能?

shell - 以十六进制序列递归搜索二进制文件的目录?