I have a function that I declare as autoloaded in my zshenv. It works fine when I call it from the zsh prompt, or from a zsh script. But when I try to call it from a Ruby script (using `my_zsh_autoloaded_function`), it fails. I know Ruby is using zsh, and I know the zshenv is being sourced. One workaround is to do `zsh -c "my_zsh_autoloaded_function"`. Is there a way to give Ruby direct access?
You can't. That's not how Unix command execution works.
Zsh is essentially a REPL just like irb.
In order to for Zsh to execute internal commands it has to do one of the following:
-c switch, or..None of those prerequisites are fulfilled when you just do `zsh_function`.
But you actually found (one of) the correct solutions already by using zsh -c.
But you were confused because you are looking at $SHELL and thinking you are running under zsh. $SHELL is not a reliable indicator of which shell is running:
> zsh
> echo $SHELL
/usr/bin/zsh
> sh
$ echo $SHELL
/usr/bin/zsh
$ bash
$ echo $SHELL
/usr/bin/zsh
$ SHELL=foo
$ bash
$ echo $SHELL
foo
So SHELL is simply copied from the originating environment into whatever new environment or shell you are spawning.
Now the final piece of the puzzle is hidden inside the Ruby source code, and also in the help file for 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.
So no, Kernel.system or backticks on Unix will not run zsh. It will always run either the program directly (for example /bin/ls) or run sh -c in case of a bash command or a command which requires any other shell processing (like ls *).
It's easy to check too:
> 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
Solution
Either run using zsh -c, like you did, or create a separate Zsh shell script with the command and run that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With