tags:

views:

465

answers:

3

I am trying to run commands from ruby via system (or by using backticks), but am running into problems. When I try to call a command, the shell is unable to find it, even though I know it works if I call it straight. For example:

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

The problem seems to be that ruby is using the sh shell, in which $PATH is not set correctly, rather than bash, and I am not sure why. The user my application is running under is set up to use bash by default.

Is there any way to tell ruby to use bash instead of sh?

+2  A: 

i'm guessing that Ruby uses the system() C function, which uses /bin/sh. In most systems, /bin/sh is just a symlink to other shell, so you can change to whatever you want

Javier
Hm. /bin/sh is indeed a symlink... to /bin/bash! So for some reason it's setting the `PATH` to be something different than it normally is?
Daniel Vandersluis
+2  A: 

As far as I know, the only way to do that is to explicitly invoke the shell, e.g.

`bash -c zip`

or

`#{ ENV['SHELL'] } -c zip`

Or with system: system("bash", "-c", command)

However ruby (and all processes spawned by ruby) should inherit the parent processes' environment and thus have $PATH set correctly even when using another shell. Do you maybe run ruby from a cron job or init script or the like, where PATH is simply not set correctly?

sepp2k
The call is being made from the web, not from cron or as a script. Could apache be changing my path?
Daniel Vandersluis
That is very likely the case yes. (Well presumably apache does not change PATH, but PATH hasn't been set to its usual value, because your rc files aren't sourced before invoking apache).
sepp2k
If you need to replace `zip` with a multi-word command, and you can't use multiple arguments (eg `IO.popen`), use escaped quotes, like `system("bash -c \"cat food\"")`
Andrew Grimm
+3  A: 

Why not just specify the full path the the zip executable.

Corban Brook
Yah, I could. The reason I haven't is that it's been developed in multiple development environments, and the path isn't necessarily the same on all of them.
Daniel Vandersluis
a command like whereis should always be in the path. or common place in all distros /usr/bin/whereis this might be a good solution for finding bins that may be scattered.
Corban Brook