would like to open an ssh session, run commands and get the output real-time as the process runs (this base will involve running additional commands on the remote server)
from subprocess import Popen, PIPE
with Popen(['ssh <server-domain-name>',
],shell=True,
stdin=PIPE, stdout=PIPE, stderr=PIPE,
universal_newlines=True) as ssh:
output1 = ssh.stdin.write('ls -l')
output2 = ssh.stdin.write('mkdir test')
status = ssh.poll()
print(output1)
print(output2)
so far this is what I have, using ssh.communicate[<command>] gives the right output but closes the subproceess after the first command, any thoughts?
worked for me
from fabric2 import Connection
with Connection('<host>') as c:
print(CGREEN +'connected succsfully!' + CEND)
#gather user info
user = io.StringIO
user = c.run("whoami", hide=True)
print(f'user found:{user.stdout} ')
#fetching files
c.run(<command>, pty=True)
Related
I am new to Python.
I am trying to SSH to a server to perform some operations. However, before performing the operations, i need to load a profile, which takes 60-90 seconds. After loading the profile, is there a way to keep the SSH session open so that i can perform the operations later?
p = subprocess.Popen("ssh abc#xyz'./profile'", stdout=subprocess.PIPE, shell=True)
result = p.communicate()[0]
print result
return result
This loads the profile and exits. Is there a way to keep the above ssh session open and run some commands?
You have to construct a ssh command like this ['ssh', '-T', 'host_user_name#host_address'] then follow below code.
Code:
from subprocess import Popen, PIPE
ssh_conn = ['ssh', '-T', 'host_user_name#host_address']
# if you have to add port then ssh_conn should be as following
# ssh_conn = ['ssh', '-T', 'host_user_name#host_address', '-p', 'port']
commands = """
cd Documents/
ls -l
cat test.txt
"""
with Popen(ssh_conn, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True) as p:
output, error = p.communicate(commands)
print(output)
print(error)
print(p.returncode)
Terminal Output:
Please let me know if you need further explanations.
N.B: You can add command in commands string as many as you want.
I tried the following code which is working perfect, but it's not taking my passphrase. when I run this code I get a popup which asks to enter the passphrase for every time I run the python code in new cmd. But I want to automate this. So please suggest a better option to take passphrase for python script itself.
from subprocess import PIPE, Popen
output_file_name = 'abc.zip'
input_file_name = 'abc.zip.pgp'
args = ['gpg', '-o', output_file_name, '--decrypt', input_file_name]
proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE,shell=True)
proc.stdin.write('passphrase\n')
proc.stdin.flush()
stdout, stderr = proc.communicate()
print(stdout)
print(stderr)
How can I execute a command on a remote server in Python and pipe the stdout to a local command? To do ssh host 'echo test' | cat in Python, I have tried
import paramiko
import subprocess
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='user')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test')
proc = subprocess.Popen(['cat'], stdin=ssh_stdout)
outs, errs = proc.communicate()
print(outs)
but I get the exception 'ChannelFile' object has no attribute 'fileno'. It seems that Paramiko's ssh_stdout can't be used as stdin with subprocess.Popen.
Yes, subprocess cannot redirect output on a "fake" file. It needs fileno which is defined only with "real" files (io.BytesIO() doesn't have it either).
I would do it manually like the following code demonstrates:
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
proc.stdin.write(ssh_stdout.read())
proc.stdin.close()
so you're telling Popen that the input is a pipe, and then you write ssh output data in the pipe (and close it so cat knows when it must end)
According to the docs, the ChannelFile object does not directly wrap an actual file descriptor (because of the decryption and demuxing and so on that occurs within SSH), so it can't directly be used as a file descriptor for Popen.
Something like
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('echo test')
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
while proc.poll() is not None: # (fixed)
buf = ssh_stdout.read(4096)
if not buf:
break
proc.stdin.write(buf)
might work; i.e. you read the SSH stdout stream manually, up to 4096 bytes at a time, and write them to the subprocess's stdin pipe.
I'm not sure how the code above will behave when the remote command exits, though, so YMMV.
I have a custom input method and I have a python module to communicate with it. I'm trying to control the shell with it so everything from local stdout is printed on the remote device and everything sent from the remote device goes into local stdin, so that remote device can control the input given to the program, like if there was an input function inside the program the remote device can answer to that too (like in ssh).
I used python subprocess to control the stdin and stdout:
#! /usr/bin/python
from subprocess import Popen, PIPE
import thread
from mymodule import remote_read, remote_write
def talk2proc(dap):
while True:
try:
remote_write(dap.stdout.read())
incmd = remote_read()
dap.stdin.write(incmd)
except Exception as e:
print (e)
break
while True:
cmd = remote_read()
if cmd != 'quit':
p = Popen(['bash', '-c', '"%s"'%cmd], stdout=PIPE, stdin=PIPE, stderr=PIPE)
thread.start_new_thread(talk2proc, (p,))
p.wait()
else:
break
But it doesn't work, what should I do?
p.s.
is there a difference for windows?
I had this problem, I used this for STDIN
from subprocess import call
call(['some_app', 'param'], STDIN=open("a.txt", "rb"))
a.txt
:q
This I used for a git wrapper, this will enter the data line wise whenever there is an interrupt in some_app that is expecting and user input
There is a difference for Windows. This line won't work in Windows:
p = Popen(['bash', '-c', '"%s"'%cmd], stdout=PIPE, stdin=PIPE, stderr=PIPE)
because the equivalent of 'bash' is 'cmd.exe'.
I'm trying to connect to SQL server using the below code I'm getting error invalid argument. I'm trying to read from a sql file and the run the query on the session created by popen using sqlcmd.
My SQL file contain this code -
select ##version;
GO
this is my python code to make connection and run the command. I'm getting "[Errno 22] Invalid argument"
import os
import subprocess
from subprocess import Popen, PIPE, STDOUT
def ms_sql_session():
ip_addr = "xxx.xxx.xxx.xxx,1433"
user = 'sa'
password = 'password'
connection_string = 'sqlcmd -S %s -U %s -P %s' %(ip_addr, user, password)
try:
session = Popen(connection_string, stdin=PIPE, stdout=PIPE, stderr=PIPE)
f = open('abc.sql','r')
str_cmd = f.read()
session.stdin.write(str_cmd)
stdout, stderr = session.communicate()
print stdout
print stderr
return True
except Exception, e:
print str(e)
return False
ms_sql_session()
How can i degug this kind of situation. I'm pretty much novice to sql hence i'm not sure that this is the problem with my code or the way stdin works.
I'm able to run command using the sqlcmd utility on command prompt. I'm using the sqlcmd for sql 2005
try this (add shell=True):
session = Popen(connection_string, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
or you can you can add explicit path of sqlcmd.exe to your string ...