如何为Ruby系统调用指定要使用的Shell?

10

我试图通过system(或使用反引号)从Ruby运行命令,但是遇到了问题。当我尝试调用一个命令时,即使我知道如果直接调用它可以工作,shell也无法找到它。例如:

`zip`
>> sh: zip: command not found

问题似乎是ruby使用的是sh shell,其中$PATH设置不正确,而不是bash,我不确定原因。应用程序正在运行的用户默认使用bash

是否有办法告诉ruby使用bash而不是sh

3个回答

10
据我所知,唯一的方法是显式地调用shell,例如:
`bash -c zip`
或者
`#{ ENV['SHELL'] } -c zip`

或者使用系统命令:system("bash", "-c", command)

然而,Ruby(以及由Ruby生成的所有进程)应该继承父进程的环境变量,因此即使使用另一个shell,$PATH也应该正确设置。您可能是从cron作业、init脚本或类似的地方运行Ruby,其中PATH未正确设置?


调用是从Web而不是从cron或脚本进行的。Apache会更改我的路径吗? - Daniel Vandersluis
1
很有可能是这样的。 (嗯,大概Apache不会更改PATH,但是因为在调用Apache之前没有源化rc文件,所以PATH没有设置为其通常值)。 - sepp2k
如果您需要将 zip 替换为多个单词的命令,并且不能使用多个参数(例如 IO.popen),请使用转义引号,例如 system("bash -c \"cat food\"") - Andrew Grimm

4
我猜 Ruby 使用 system() C 函数,该函数使用 /bin/sh。在大多数系统中,/bin/sh 只是一个指向其他 shell 的符号链接,因此您可以更改为任何您想要的。

嗯。/bin/sh 确实是一个符号链接...指向 /bin/bash!所以出于某种原因,它将“PATH”设置为与通常不同的内容? - Daniel Vandersluis

0
为什么不直接指定zip可执行文件的完整路径呢?

是的,我可以。但我还没有这样做的原因是它在多个开发环境中开发,路径并不一定相同。 - Daniel Vandersluis
2
像whereis这样的命令应该总是在路径中,或者在所有发行版的常见位置 /usr/bin/whereis。这可能是查找可能分散的bins的好方法。 - Corban Brook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接