Sending two commands over ssh in one subprocess.Popen list - python

#!/usr/bin/python
import subprocess
import sys
HOST=raw_input("\nInsert server(ex: xxXX.city):\n\n")
IP=raw_input("\nInsert ip:\n\n")
print ''
COMMAND='show arp hostname %s' % IP
COMMAND2='show route table inet.0 %s' % IP
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND, COMMAND2],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if result == 'xxx':
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
else:
print ''.join(result)
I get this error:
error: syntax error: show
I'm guessing there is a problem with two commands chained in a subprocess.Popen. I say this because it looks like it executes each one with no problem. It's only when I put them chained that I get the error. I looked it up but I haven't found something clear about making two commands in one go with Popen..is there a way to make them work like the above but with a little twist or do I have to change the subprocess? thank you

with help from a friend the problem got solved like this:
ssh = subprocess.Popen(["ssh", "%s" % HOST, ';'.join([COMMAND, COMMAND2])],

Related

How can I put result from rfcomm shell command in to a variable in python?

I am using this script in python in order to connect to a Bluetooth device and then get data, but I want to know the result of this shell command in order to do next works
import os
import time
import signal
import subprocess
p = subprocess.Popen("sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1",shell=True)
(stderr,stdout) = p.communicate()
print 'stderr: [%s]' % stderr
print 'stdout: [%s]' % stdout
time.sleep(5)
while True:
print "Device is ready"
time.sleep(5)
this code is a sample when I run the command:
"sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1"
in shell, it returns:
Connected /dev/rfcomm0 to XX:XX:XX:XX:XX:XX on channel 1
Press CTRL-C for hangup
but how can I put above result in a variable, because I need to know the result of this command?
I use stdout, stderr in subprocess but does not work.
I am using python 2.7
Python subprocess and user interaction
above link talk about getting output in a variable in general, but the problem in my question related to rfcomm, which does not put its result in variable, I run those script and they works well, but it does not works when it used with rfcomm command
If you're using Python 3.5 or higher,
you can use run instead. That way you'll have access directly like so,
result = subprocess.run(["sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1"], stdout=subprocess.PIPE)
Then access what you want like this,
result.stdout
If ever you use Python 2.7, as suggested by documentation I linked, they redirect you to the Older high-level API section.
From there you'll notice that you could use check_output
result = subprocess.check_output(["sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1"])
Note, if ever you want to catch error also use the stderr=subprocess.STDOUT flag.
result = subprocess.check_output("sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1", stderr=subprocess.STDOUT, shell=True)
Lasty, there is an important not you should be aware,
By default, this function will return the data as encoded bytes. The actual encoding of the output data may depend on the command being invoked, so the decoding to text will often need to be handled at the application level.
EDIT
Since your goal seems to get output while running. Take a look at this answer. I prefer linking instead of re-inventing the wheel.
You may need to issue the CTRL+C command before the data is returned.
Send a signal and catch the exception to deal with what is returned.
import os
import time
import signal
import subprocess
stream = []
try:
p = subprocess.Popen("sudo rfcomm connect /dev/rfcomm0 XX:XX:XX:XX:XX:XX 1",shell=True)
#(stderr, stdout) = p.communicate()
#print 'stderr: [%s]' % stderr
#print 'stdout: [%s]' % stdout
#time.sleep(5)
#print "Device is ready"
time.sleep(5)
os.kill(p.pid, signal.CTRL_C_EVENT)
p.wait()
except KeyboardInterrupt:
#except Exception:
for line in p.stdout: #May also be p.stderr
stream.append(line)
for x in stream:
print(x)

trying to write code in python that will loop through server names in a url

This is what i have it works when there is only 1 server name in the URL It reads from. But when there is any more than the one server name it doesn't work. so i'm trying to do a loop however it loops through each character instead of each line. Im writing this in python 2.7. any advice
#!/usr/bin/python2.7
import urllib2
import subprocess
import sys
def stuff ():
data = urllib2.urlopen('url')
next(data)
for line in data:
return(line).rstrip
HOST=stuff()
COMMAND= "uname -a"
for i in HOST:
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if result == []:
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
else:
print result

To read data from Putty and store it in another file by Python

I need a script in Python that will collect the logs/information from PUTTY and then need to store this information in an another file saved in drive.
import subprocess
import sys
HOST="127.0.0.1"
# Ports are handled in ~/.ssh/config since we use OpenSSH
COMMAND="uname -a"
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if result == []:
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
else:
print result

Running commands on remote server and saving the result to a string variable in a Python script [duplicate]

This question already has answers here:
Python how to read output from pexpect child?
(8 answers)
Closed 6 years ago.
How can I run commands on the remote server to which I login to, using pexpect and store the result in the form of a string into a variable?
I made a connection to the server in the following way:
COMMAND_PROMPT = '[#$] '
TERMINAL_PROMPT = '(?i)terminal type\?'
TERMINAL_TYPE = 'vt100'
SSH_NEWKEY = '(?i)are you sure you want to continue connecting'
child = pexpect.spawn('ssh -l %s %s'%(loginuser, servername))
i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password'])
if i == 0: # Timeout
print('ERROR! could not login with SSH. Here is what SSH said:')
print(child.before, child.after)
print(str(child))
sys.exit (1)
if i == 1: # In this case SSH does not have the public key cached.
child.sendline ('yes')
child.expect ('(?i)password')
if i == 2:
# If a public key was setup to automatically login
pass
if i == 3:
child.sendline(password)
# Now we are either at the command prompt or
# the login process is asking for our terminal type.
i = child.expect ([COMMAND_PROMPT, TERMINAL_PROMPT])
if i == 1:
child.sendline (TERMINAL_TYPE)
child.expect (COMMAND_PROMPT)
Now suppose I want to execute the following command on the server I logged in to and save the result to a string in my python script itself:
ps -ef|grep process1
How can this be done?
I think this might help you.
import subprocess
import sys
url="http://www.anyurlulike.any"
# Ports are handled in ~/.ssh/config since we use OpenSSH
COMMAND="uname -a"
ssh = subprocess.Popen(["ssh", "%s" % url, COMMAND],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if result == []:
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
else:
print result
You can use read() function, it will give you the entire output.
result = child.read()

Getting error while executing ping through subprocess.call()

I have given
subprocess.call(['ping', '127.0.0.1', '>>', 'out15.txt'])
statement in python script.
But I am getting unknown host error.
Please let me know why I am getting that error.
Cause you pass the >> out15.txt to the ping as argument.
The >> is special character of cmd\bash. If you insist to redirect the output to file with the command, instead using python code you can do that like this:
subprocess.call(['cmd', '/c', 'ping', '127.0.0.1', '>>', 'out15.txt'])
The same for bash.
As #Ori Seri pointed out >> is usually interpreted by a shell:
from subprocess import call
call('ping 127.0.0.1 >> out15.txt', shell=True)
Note: the string argument with shell=True.
You could do it without the shell:
with open('out15.txt', 'ab', 0) as output_file:
call(["ping", "127.0.0.1"], stdout=output_file)
Note: the list argument with shell=False (the default).
You don't need to write the output file to interpret the ping results; you could use the exit status instead:
from subprocess import call, DEVNULL
ip = "127.0.0.1"
rc = call(["ping", '-c', '3', ip], stdout=DEVNULL)
if rc == 0:
print('%s active' % ip)
elif rc == 2:
print('%s no response' % ip)
else:
print('%s error' % ip)
See Multiple ping script in Python.

Categories

Resources