0

I am trying to run a PHP script inside the ruby shell. While it is working perfectly if I am using the snippet directly in the ssh terminal, it is returning an error if executed with ruby:

zsh:1: command not found: php

Using this script below with commands like ls is working fine.

require 'rubygems'
require 'net/ssh'

host = "abc.de"
user = "user_xy"
pass = "user_pass"

begin
    Net::SSH.start(host, user, :password => pass) do |ssh|
        $a = ssh.exec! "cd xy_dir && php abc.phar do_this"
        ssh.close
        puts $a     
end
rescue 
    puts "Unable to connect to #{host}."
end

How can I run PHP using Net::SSH?

Thanks for your help

timiTao
  • 1,417
  • 3
  • 20
  • 34
D. Ne
  • 1
  • 2
    1) Have you tried from within Ruby doing `\`ssh host password command\``? This might help narrow down the problem. 2) I recommend removing the `ssh.close` command; the ssh session will be closed automatically when the block terminates. (File.open with a block works this way too.) 3) You may need to use `Shellwords.escape` on any strings you pass to a shell. 4) You should not need the `require 'rubygems'`. 5) Are you absolutely sure that both cases (the success and the failure) are running on the same host? – Keith Bennett Feb 13 '18 at 13:29
  • 1
    With regards to (1) above, the problem may be to do with the environment in which SSH is running the command. Where is the PHP executable on the host machine? Is that folder in the `$PATH` when you ssh to the machine? – Tom Lord Feb 13 '18 at 13:43
  • @KeithBennett 1) I am not sure what you're meaning. I am just learning Ruby, but I have some experience with Javascript and PHP. 2) Okay, ssh.close is removed. 3) I tried Shellwords.escape but it returns zsh:1: no such file or directory: ... 4) Thanks, removed too 5) Yes, absolutely. I copy and pasted the command and it runs. – D. Ne Feb 13 '18 at 14:50
  • @TomLord Can you specify what you're meaning exactly? Like I stated above, the snippet is running. The shortened version in the code example is pointing actually to ~/.php/abc.phar in the real file. – D. Ne Feb 13 '18 at 14:50
  • @D.Ne When you execute `php` on the command line, what executable is that actually running? Try: `which php`, too see. Now, run: `echo $PATH`, you should also see that folder in which the `php` executable lives. Now, try doing to above via the ruby script. What's the difference? – Tom Lord Feb 13 '18 at 15:03
  • @TomLord SSH: "which php" returns "php: aliased to /usr/local/bin/php5-56LATEST-CLI" and echo $PATH returns "/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/5.4.0:/usr/local/bin:/directory/8239293/bin". Via Ruby "wich php" is returning "php not found" and echo $PATH is returning "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/user/.rvm/bin" But why can I connect via ruby and can execute commands like "ls"? Simple commands like that is working. PHP not. – D. Ne Feb 13 '18 at 15:16
  • There you go, you've found the cause: "php: **aliased** to..." --- When you log into the server, you're somewhere setting an **alias** for PHP. Possibly in the `~/.bashrc`? However it's been implemented, this alias isn't getting triggered when you connect via SSH in ruby. – Tom Lord Feb 13 '18 at 15:38
  • To prove the point, if you run `php5-56LATEST-CLI abc.phar do_this` in the ruby script it will work. But a better solution would either be to (somehow?) trigger loading that same alias, or even replace the alias with something more concrete, e.g. a symbolic link. I don't know how you've installed PHP, so can't really advise on best practice there.... – Tom Lord Feb 13 '18 at 15:40
  • Thank you for your help. It's working. But: I never installed php on this shared hosting server. 'cd ruby && /usr/local/bin/php5-56LATEST-CLI ~/.php/abc.phar do_this' is indeed working. I am curious while the path is missing it is working inside SSH but with Ruby it needs to be specified. – D. Ne Feb 13 '18 at 16:09
  • It's not really a ruby issue; it's because you're connecting without a login shell (i.e. Loading in a different environment, like I originally said) – Tom Lord Feb 14 '18 at 08:16
  • For example, [here](https://github.com/mitchellh/net-ssh-shell) is a ruby gem that connects *via a login shell*. But it would be better if you could somehow change the host machine to eliminate the need for this in the first place. – Tom Lord Feb 14 '18 at 09:58

1 Answers1

1

I think the problem is not with Ruby per se, but probably with any language's SSH implementation. When using the language's ssh support to create an ssh session, it does not create a login shell (which would read initialization files such as .bashrc), but rather, a lower level interface to the machine.

Therefore, some functionality you would expect from normal shell use will be missing when connecting with Ruby's Net::SSH.

I was thinking there may be a way to get around this by calling bash -l -c "[the commands]", to force a login shell with bash's -l flag, and -c command specifier, but could not get it to work.

I did find this other SO issue whose answer discusses an awkward workaround that probably is not worth trying: ruby net-ssh login shell.

Keith Bennett
  • 4,722
  • 1
  • 25
  • 35