Execute Linux script (expect) within Matlab with system() - linux

Matlab R2015a
Hello,
In order to programmatically ssh connect I made an expect script as explained in
ssh connect and commands programmatically
#!/usr/bin/expect
set login "any_user"
set addr "some_address"
set pw "any_pwd"
spawn ssh -t $login#$addr
expect "$login#$addr\'s password:"
send "$pw\r"
expect "~" ; # put here string from your server prompt
send "mkdir some_dir\r"
interact
I called this script LoginSSH.sh (of course, with my own data), then I run this command in the Linux console without problems:
./LoginSSH.sh
The idea was to run this command from Matlab with system():
scmd='./LoginSSH.sh'
[status,cmdout]=system(scmd)
But for some reason Matlab has some problems to execute the script via system(). This is the output:
status =
1
cmdout =
OpenSSL version mismatch. Built against 100020af, you have 1000107f
send: spawn id exp4 not open
while executing
"send "$pw\r""
(file "./LoginSSH.sh" line 8)
I can even run the command in Python:
import os
from subprocess import call
call(["./LoginSSH.sh"])
again, without any problems.
What could be the reason Matlab won't like to run the shell script?
Thanks in advance.
jleon

Related

Expect: get back from SSH

I am trying to write an expect script that:
1, Logs in to my raspberry pi via SSH
2, Does something in the raspberry pi
3, sends "exit\r" to get back to my computer
4, Does something on my computer
My current sollution looks like this:
#!/usr/bin/expect
set timeout -1
spawn ssh pi#XXXXXXXX
expect "*: "
send "raspberry\r"
expect "pi#"
# Do something here
send "exit\r"
expect "username#"
send "pwd" # pwd just as a test
expect eof
The error I'm getting is:
send: spawn id exp6 not open
while executing
"send "pwd""
I have tried googling, but can't find anything that solves this question.
I would be really thankful if someone could help me!
Well, you're spawning the ssh program. When you exit from the remote session, ssh ends, and now you don't have a running process to interact with.
Expect has another mechanism to invoke external programs: there's spawn but also exec. This does not provide any interactivity: the exec'ed program just runs and exits (and returns its output).
So, it depends on what "something" you want to do:
spawn bash on your local machine to then use with send & expect
exec something.
In addition to the expect(1) man page, since Expect is a Tcl extension, there are also the Tcl commands to use.

Running commands in server through local python script

I would like to run a batch of bash commands (all together) in a server shell through a python3 script in my local machine.
The reason why I'm not running the python3 script on my laptop is that I can't create the same environment on the server and I want to keep the settings I have on my machine while executing the script.
What I would like to do is:
-Run python commands locally
-Run at a certain point those command on the server
-Wait for the end of server execution
-Continue running python script
(This will be done in a loop)
What I'm trying is to put all the commands in a bash script ssh_commands.sh and use the following command:
subprocess.call('cat ssh_commands.sh | ssh -T -S {} -p {} {}'.format(socket, port, user_host).split(),shell=True)
But when the execution of the script reaches that line get stuck until subprocess.call timeout. The execution of the script anyway won't take that much. The only way to stop the script before is through Ctrl+C
I've also tried to set up the ssh connection in the ~/.ssh/config file but I'm getting the same result.
I know that ssh connection works fine and if I run ssh_commands.sh on the server manually, it runs without any problem.
Can somebody suggest:
- A way for fixing what I'm trying to do
- A better way for achieving the final result written above
- Some debugging way to find out what could be the problem
Thank you in advance
To expand on my comment - and I haven't tested your specific case with ssh, could be there are other complications there). This is actually copy/pasted from my own code in a situation that I already know works.
from subprocess import Popen, PIPE, DEVNULL
from shlex import split as sh_split
proc1 = Popen(sh_split(file_cmd1), stdout=PIPE)
proc2 = Popen(file_cmd2, shell=True, stdin=proc1.stdout, stdout=PIPE)
proc1.stdout.close()
I have a specific reason to use shell=True in the second, but you should probably be able to use shlex.split there too I'm guessing.
Basically you're running one command, outputting to `PIPEĀ“, then using this as input for the second command.

how to execute shell script from soapui groovy script?

I have shell script which is kept on remote server(linux machine) and I am trying to call that shell script in between the execution of various test cases of SOAPui from windows.
So I have prepared a groovy script:
def command="/usr/bin/ssh -p password username#IP_address bash -s < /home/test.sh"
def proc=command.execute().text
proc.waitFor()
But unfortunately, I am receiving an error:
java.io.IOException: Cannot run program "/usr/bin/ssh": CreateProcess error=2, The system cannot find the file specified error at line: 6
I tried to search more on this, but couldn't get the resolution. Some of the links were:
How to execute shell script using soapUI
http://groovy-lang.org/groovy-dev-kit.html#process-management
If as you comment you've a putty.exe installed on Windows you can try with the follow.
First of all create a file in your Windows local with the commands to execute remotely for example I create the follow C:/temp/commandsToRunRemotely.txt then in this file put the command you want to execute. As a sample I use the follow command:
echo "test remote execution" > /tmp/myfile.txt
Then from groovy script in SOAPUI call putty.exe passing the local file which contains the commands to execute remotely:
def command = "C:/path/to/putty.exe -ssh user#IP -pw pass-m C:/temp/commandsToRunRemotely.text"
def proc = command.execute()
proc.waitFor()
Note that if you've putty.exe in your Windows path, you can simply use putty.exe instead of full path.
This is only an ilustation sample, but if you want to execute a shell script remotely instead of echo "test remote execution" > /tmp/myfile.txt in the commands file use directly the path for your script: /home/test.sh
I get the Putty command line options from this nice answer
Hope it helps,

call "ssh" in system function in perl

i have a question related to connecting via ssh with "system()" function in perl.
in my perl script i want to connect via ssh to another ip, run a command and return its value or redirect result value to a file.
system ("su - anotherUSer ; ssh someUsername#someIpAddress");
(i change my username so that i am not asked for a password)
when i execute this only line it changes the username correctly but not connects via ssh. In other words, the second part of the system call is not done (or is done but not reflected on the terminal).
If i enter mannualy to the server where this script executes and run this two commands, i can run them without errors.
When i run "exit" command to logout my anotherUser user an error raises:
(ssh: "username"."ip": node name or service name not known)
I also tested it escaping '#' and '.'
system ("su - anotherUSer ; ssh someUsername\#number\.number\.number\.number");
in this case when i run the "exit" command, it askes for the password(Remember that i swiched users so that password could be ommited).
I hope you understand my problem.
Thanks!!!
You're telling the wrong shell to execute ssh.
You spawn a shell and ask it to execute two commands, su and ssh. It first spawns su, which launches another shell. You didn't tell this new shell to do anything, so it waits for input. When it finally exits, the first shell executes the second command, ssh.
Use:
system("su -c 'ssh someUsername#someIpAddress' - anotherUSer");
But that's nasty! Why not just set up a key for the current user instead of becoming anottherUSer to use theirs?

Running Multiple Remote Commands Consecutively Through Matlab system()

I'd like to execute multiple commands consecutively using a matlab system call. I would first like to ssh into a remote machine then run a program on that machine. After the program starts I would like to then enter another command into this program's console. Here is what I would like to do in code:
system('ssh othermachine')
system('command on other machine')
%%WAIT FOR PROGRAM TO START RUNNING ON OTHER MACHINE
system('run command on other machine')
The problem is that Matlab will hang on the first system call and won't proceed to the next system call until the process form the first is exited. Is there a way around this?
Thanks for your help!
Prologue: Your problem is general and not just related to matlab.
When you want to run remote commands via ssh, they have to be issued in the ssh call. In a (linux) shell, you'd have
$ ssh remotemachine command1
for a single command. Hence, using a matlab system call you would have
>> system('ssh remotemachine command1').
When you want multiple commands to be executed sequentially, in a shell you'd write
$ ssh remotemachine "command1; command2"
i.e., in matlab, you'd write something like
>> system('ssh remotemachine "command1; command2"').
In general, is way more elegant to group your commands in a shell script, say script.sh, and pipe it in the ssh call
$ cat script.sh | ssh remotemachine
which, in matlab shell, sounds like
>> system('cat script.sh | ssh remotemachine').
There are a number of flags you can add in order to specify which behavior you want (e.g. in terms of session detachment/background execution, output collection,... look e.g. here).

Resources