Ruby: Execute php commands via SSH - php

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

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.

Related

virtctl works when executed via command line but not from php exec()

I am trying to run kubectl virt commands to manage my virtual machine via PHP. First, I log in to my server with phpseclib with the following code:
$ssh = new SSH2('localhost');
if (!$ssh->login('root', 'rootPassword')) {
throw new \Exception('Login failed');
}
This part works fine, and when I try to run $ssh->exec('whoami && echo $PATH'), I get the following output:
root
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
But, whenever I try to run kubectl virt via PHP, I get the following output:
error: unknown command "virt" for "kubectl"
kubectl and kubectl virt work perfectly fine when I run them via terminal but somehow do not work with PHP exec(). I also tried to check the $PATH via terminal and I get a different output:
/root/.krew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
I thought that it may be because of $PATH but the interesting part is when I try to run sudo kubectl virt via terminal I also get the same error:
error: unknown command "virt" for "kubectl"
At that point, I am completely lost and don't even know where to look for a problem. I am thankful for all the answers.
When you are issuing ad-hoc ssh commands, you are not using interactive shell, and depending on your default shell behavior it may or may not load your .bashrc file . See https://serverfault.com/questions/936746/bashrc-is-not-sourced-on-ssh-command and Running command via ssh also runs .bashrc? for more details.
So by default, krew modifies your PATH variable, and appends it's bin path to it, i.e. my config contains export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH". But what exactly is kubectl plugin? Usually it's just a single binary, with kubectl-plugin_name name. So by invoking which kubectl-virt you can easily know where is your virt binary located and invoke it directly, so something like
$ssh->exec('~/.krew/bin/kubectl-virt')
should work
The other way is to modify PATH all by yourself, setting PATH=$PATH:~/.krew/bin should make it work, at least in my case
ssh localhost 'PATH=$PATH:~/.krew/bin kubectl virt'
worked nicely.
You can try to force loading of .bashrc in your shell configuration, but personally i think it's a bad practice, and ssh commands are not usually loading rc files for a reason, command execution speed and consistency between systems are the first things that come to mind.
Regarding sudo, it's actually not that surprising, because without -E or -i flags it won't load your current environment / won't start interactive shell. See https://unix.stackexchange.com/questions/228314/sudo-command-doesnt-source-root-bashrc for more info

How to call php (stored on a server) using vba/vbs

I want to call php using vba or vbs. The php file is stored on a server.
I am able to do it if the php file is stored locally:
Sub asasdsad
Call Shell("C:\xampp\php\php.exe C:\path\file.php", 1)
End Sub
This calls the php which executes a code for me. My problem is, the .php file I want to call is stored on a server, for which I've got username and password of course. Copying file to local directory is not an option as it's got a lot of includes.
My idea is to use PuTTY to connect to the server, and use it to execute above command, all from cmd using vba/vbs.
UserName = "un"
Passwrd = "pw"
'this would need additional parameters at the end to call php.exe like above
Call Shell("""C:\Program Files (x86)\PuTTY\putty.exe"" " & "-ssh " & UserName & "#ip address -pw " & Passwrd, 1)
As you can imagine there will be a lot of parameters so it just get complicated, not ever sure if this would work. I've never used PuTTY and all of this is quite new to me. I'm sure there's a better way?
First, do not use PuTTY, use Plink (PuTTY connection tool). It's a console application designed for automation (contrary to PuTTY, what is GUI application, designed for an interactive use).
Plink (again contrary to PuTTY) can accept a command to be executed on its command-line (it has a similar command-line syntax as OpenSSH ssh):
"C:\...\plink.exe" -ssh username#ip_address -pw password /path/to/php /path/to/script.php

How to get result from a command executed in PHP on remote SSH server using PuTTY?

I'm trying to execute a command on my Raspberry Pi via SSH and get the result of it in my PHP script on my Windows machine. Currently I can execute the command on my RasPi, but I do not get any results back into the PHP script.
The code I'm Using for this:
<?php
$cmd = "C:\\path_to_putty\\putty.exe -ssh pi#RasPiIP -pw raspberry -m C:\\path_to_test.txt\\test.txt";
$result = shell_exec($cmd);
echo $result;
?>
For sending commands to my RasPi the code works. I have tested multiple times by as example changing test.txt to sudo reboot and it worked as intended.
I'm using PuTTY to send my command (test.txt is currently nfc-list which returns connected Scanners etc not important right here) to the RasPi.
What I want to achieve is that $result contains the returned data when my command is executed.
Is it even possible to do that? If yes how (any help appreciated). If no, are they maybe other ways to approach this?
Addressing the possible duplicate: I am using a Windows Machine and also I'm trying to get the result (of the one command) to reuse in my PHP script. In the other question, user is trying to save the full console log and save it to another file.
First, do not use PuTTY. PuTTY is a GUI application intended for an interactive use. Use Plink, which is command-line/console equivalent of PuTTY intended for command automation. Being a console application, it has a standard output, which can be read in PHP (PuTTY as a GUI application does not have standard output).
With Plink, you can also specify the command on Plink command line, so you do not need to create the test.txt command file.
In any case, there's no way to make PuTTY or Plink separate an output of command only (at least not from a command-line).
But what you can do, is to print some header/trailer to distinguish the start and end of the command output, like:
plink.exe -ssh pi#RasPiIP -pw raspberry "echo start-of-command && command && echo end-of-command"
And then in PHP, you can look for the start-of-command and end-of-command to identify what part of Plink output is really the command output.
In any case, you better use a PHP SSH library to achieve what you want, rather then driving an external application. For example phpseclib. But that's a completely different question.

Is it possible to programmatically launch the php interactive shell from a file?

I would like to be able to either launch php in interactive mode via phing or via PHP (worst case scenario, phing can run an adhoc task with the desired code).
I've gotten this far:
<?php
$cmd = 'php -d auto_prepend_file=bootstrap.php -a';
passthru($cmd)
And the above almost gets me what I want. I enter a shell I can interact with, but the prompts are gone (the php > at the start of each line), all meta-commands (e.g., \>) totally fail, and typing exit; does nothing instead of exit the shell. So, as you can see, this isn't the ideal shell. Is this even possible without installing phpsh?
Thanks in advance.
I think PsySH will give you want you want. It's a PHP REPL that gives you the option to configure it to automatically include a bootstrap file.

Unexpected behavior when calling a Ruby script via PHP's shell_exec()

I have a Ruby script that's being used to do some API calls/screen scraping, but our main app is in PHP. Our PHP app is using shell_exec() to call the Ruby script.
The ruby script works great when called from the command lineā€“but it will randomly exits early when called via PHP's shell exec.
Here's an example of the Ruby script:
#!/usr/bin/env ruby
require 'rubygems'
require 'mysql'
require 'net/http'
require 'open-uri'
require 'uri'
require 'cgi'
require 'fileutils'
# Bunch of code here ... works fine
somePath = 'http://foo.com/bar.php'
# Seems to always exit when I do a Net::HTTP or open-uri call
post = Net::HTTP.post_form(URI.parse(somePath),{'id'=>ID,'q'=>'some query'})
data = post.body
# OR
data = open(somePath).read
# More code here ...
So, all I can deduce so far is that it's always exiting when I try to grab/read an external URL via net/http or open-uri calls. The pages I'm grabbing can accept POST or GET requests, but it seems to be exiting either way.
I'm outputting the results with PHP after the shell_exec call, but there are no error messages or exits. I do have messages being output by my Ruby script with "puts ...." here and there. Could that be a problem (I'm thinking 'no' because it doesn't exit with earlier puts messages)?
Again, it works fine when called from the shell. It's almost like the shell_exec call isn't waiting for the net/http call to finish.
Any ideas?
I'm not sure on this, but given your explanation, which sounds plausible, have you looked at all at proc_open:
http://us3.php.net/proc_open
Ruby's open-uri requires tempfile, so I'm guessing there's a file ownership conflict between you running your ruby script and the web server running it. Can the web server create a temp file using tempfile?
Just an FYI, I never really uncovered why this was happening. The best I could deduce was that some type of permission issue was preventing Ruby's open-uri commands from working properly.
I opted for queuing these jobs in a db table and running my ruby script via cron periodically. Everything seems to work fine when the ruby script runs with root/sudo perms.
Run on Linux terminal:
sudo -H -u <user> bash -c <your code> where <user> is the Apache's user.
To find Apache's user you can echo("shell_exec(\"whoami\")"); inside your code and run it on browser. whoami works on Linux and Windows, but if you're under Windows, the Apache default user is your user. You can test it anyway in case it's different, but I can't tell how to run the code on Windows like if it's Apache running it.
After that you can have a clue of what's happening. In most cases the problem is the Apache's root folder is different from operating system's folder. So when you run a command with absolute path, the OS consider / and Apache consider /var/www/html on Linux, /opt/lampp/htdocs on Xampp(Linux) and C:/xampp/htdocs on Xampp(Windows). You get the idea i think.

Categories