I am using paramiko to start a process in remote server.
With below code even if process is getting started or not ,it's printing 'not able to start'.
Not able to figure out issue here.
stdin, stdout, stderr = ssh.exec_command("{0}/minidiameterd -f {0}/BasicDiam1".format(minidiam_path))
stdin, stdout, stderr = ssh.exec_command("pgrep minidiameterd")
output = stdout.readlines()
if not output:
print "Not able to start minidiameterd"
Can you try
output = stdout.read.splitlines()
Related
some one know, how can i use variable to execute on remote host with paramiko?
For example i try to put multiple files and execute/make executable it.
SRCFILE='/root/test1.py'
DSTDIR="/tmp/"
dstf= 'runremote.py'
stdin, stdout, stderr = ssh.exec_command("chmod +x" + '' + DSTDIR + dstf)
This lines are only for example not the Script.
My issue, i get nothing from stdout and the file are untouched.
if i run stdin, stdout, stderr = ssh.exec_command("chmod +x /tmp/runremote.py") get output on stdout and my file is changed.
I am finding hard to run a process on a remote SSH server at background using Paramiko. I used :
stdin, stdout, stderr = ssh.exec_command('executefile.py &')
and found that no process of executefile.py was found running.
Then I tried using other way as including a backward slash:
stdin, stdout, stderr = ssh.exec_command('executefile.py \&')
This method worked. There was an instance running on machine but no surprise, it was not running at background. I could come to know as it is not running at background as when code stuck at second line after this code. It was
all_inf = stdout.readlines()
Now code was not going beyond above line unless the process of the script was killed.
I am learning Paramiko, any help is appreciated.
I've tried all the methods described here and here without success, and finally realized that you need to use channels instead of using the SSHClient directly for calling exec_command (this does not work in background):
client = paramiko.SSHClient()
client.connect(ip_address, username='root', pkey=paramiko_key, timeout=5)
client.exec_command('python script.py > /dev/null 2>&1 &')
You should create and use a channel, this works in background:
client = paramiko.SSHClient()
client.connect(ip_address, username='root', pkey=paramiko_key, timeout=5)
transport = client.get_transport()
channel = transport.open_session()
channel.exec_command('python script.py > /dev/null 2>&1 &')
So nohup, dtach, screen, etc, are actually not necessary.
You can try:
stdin, stdout, stderr = ssh.exec_command('nohup python executefile.py >/dev/null 2>&1 &')
exec_command isn't executing the command in an interactive shell, so "running a process in the background" doesn't really make sense.
If you really want to do this, you could use the command nohup to start your process, and keep it alive when the session exits. Remember that you can't get stdin, stdout, or stderr when you do this, since you are detaching the process from the shell, so redirect them accordingly.
I tried transport class and it was really great. Here's the code I used:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname = "host_ip", username = "un"], password = "up")
channel = ssh.get_transport().open_session()
pty = channel.get_pty()
shell = ssh.invoke_shell()
shell.send("cd /my/directory/; nohup ./exec_name > /dev/null 2>&1 &\n")
But I still don't know how to kill it using python scripts; I have an open question about it here.
EDIT 1:
I have solved my problem about killing the process somehow; you can check it.
You could try using screen
screen -d -m ping 8.8.8.8
This is would start a screen and ping 8.8.8.8. You can view this screen by using
screen -ls
and attach using
screen -D <<screen_name>>
Note that the screen will terminate after the command has finished executing.
I'm using Python's Paramiko module to SSH into a remote machine and Tar/ZIP a folder with a LOT of files (over 14K files and 60+gigs of data). The resulting zip is around 10 gigs itself. Now I can run the command to zip/tar directly from the machine with no problem. However, when I try to run the same command through SSHClient.exec_command, it runs for a bit, but eventually the zipping process on the remote machine goes to sleep. And the recv_exit_status just hangs indefinitely. Here is the code I'm using:
stdin, stdout, stderr = ssh.exec_command('cd myDirectory; tar -zcvf output.tgz *')
status = stdout.channel.recv_exit_status()
I also tried using Zip.
stdin, stdout, stderr = ssh.exec_command('cd myDirectory; find -name "*.gz" | zip output.zip -#')
status = stdout.channel.recv_exit_status()
In both cases, if I run the command directly from the remote machine, it finishes zipping/TARing. The result file is is like 9 gigs. But when I try it from Paramiko, it starts, goes more than half way (6ish gigs) and then the process goes to sleep!
I've monitored the processes on the remote machine using top, and the zip/tar WILL start running, but it will eventually go to sleep before finishing. And the python script will hang indefinitely.
Any ideas why this is happening?
It could be a timeout related. Try adding timeout param (in seconds) to the call: exec_command(timeout=20*60). This is 20 min example.
See doc string from that method for more info:
def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False):
"""
Execute a command on the SSH server. A new `.Channel` is opened and
the requested command is executed. The command's input and output
streams are returned as Python ``file``-like objects representing
stdin, stdout, and stderr.
:param str command: the command to execute
:param int bufsize:
interpreted the same way as by the built-in ``file()`` function in
Python
:param int timeout:
set command's channel timeout. See `Channel.settimeout`.settimeout
:return:
the stdin, stdout, and stderr of the executing command, as a
3-tuple
:raises SSHException: if the server fails to execute the command
"""
Also there is another issue that i experience which could also contribute: https://github.com/paramiko/paramiko/issues/109
Try my suggestion in https://github.com/paramiko/paramiko/issues/109#issuecomment-111621658
I also experienced this issue it is due to stdout.channel.eof_received == 0
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("1.1.1.1", username="root", password="pass")
stdin, stdout, stderr = client.exec_command("service XXX start")
stdin, stdout and stderr are staying open...
>>> print stdin
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>
>>> print stdout
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>
>>> print stderr
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>
So EOF was not received...
>>> print stdin.channel.eof_received
0
Usually I receive True and can just stdout.read(), but to be safe i use this workaround (which works!): Wait for a timeout, force stdout.channel.close() and then stdout.read():
>>> timeout = 30
>>> import time
>>> endtime = time.time() + timeout
>>> while not stdout.channel.eof_received:
... sleep(1)
... if time.time() > endtime:
... stdout.channel.close()
... break
>>> stdout.read()
'Starting XXX: \n[ OK ]\rProgram started . . .\n'
>>>
My solution is client.exec_command('my_cmd', get_pty=True).
get_pty=True can Request a pseudo-terminal from the server.
So If you can run your command in ssh session, then should also work by using exec_command() function.
I just had a similar thing happen to me. I can run a command when logged in via ssh, but running through exec_command eventually puts the command to sleep (S in htop). I found that it might be due to the command producing too much output on either stderr or stdout which I have gathered can overflow buffers, causing the signal that the command has finished to be lost, but I'm definitely no expert. What I did find is that adding > /dev/null 2>&1 to the end of my command (thereby eliminating the need of paramiko to touch stdout and stderr) allows the same command to finish via exec_command.
In summary, my workflow looks like this:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('999.99.99.99', username='me', key_filename='my_key')
stdin, stdout, stderr = ssh.exec_command('my_command > /dev/null 2>&1')
stdout_content = stdout.read()
stderr_content = stderr.read()
ssh.close()
This works for now, but I would still be very interested if someone knows how to fix the original problem without having to change the command to redirect stdout and stderr.
I am creating one user and want to set the ssh key for that user
My script is
import paramiko
ssh_conn = paramiko.SSHClient()
ssh_conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_conn.load_system_host_keys()
ssh_conn.connect('localhost', username='test', password='test')
cmd = 'ssh-keygen -t dsa'
stdin, stdout, stderr = ssh_conn.exec_command(cmd)
stdin.write('\n')
stdin.flush()
stdin.write('\n')
stdin.flush()
stdin.write('\n')
stdin.flush()
print "Output: ", stdout.read()
But its seems not working
When i run it as single statement copy past on python console then it works but when i run it as single python script it hang at last line print "Output: ", stdout.read().
Thx in advance for your help :)
Before attempting to read the stdout issue:
stdin.channel.shutdown_write()
See also this question for reference.
I'm trying to run an interactive command through paramiko. The cmd execution tries to prompt for a password but I do not know how to supply the password through paramiko's exec_command and the execution hangs. Is there a way to send values to the terminal if a cmd execution expects input interactively?
ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
Does anyone know how this can addressed? Thank you.
The full paramiko distribution ships with a lot of good demos.
In the demos subdirectory, demo.py and interactive.py have full interactive TTY examples which would probably be overkill for your situation.
In your example above ssh_stdin acts like a standard Python file object, so ssh_stdin.write should work so long as the channel is still open.
I've never needed to write to stdin, but the docs suggest that a channel is closed as soon as a command exits, so using the standard stdin.write method to send a password up probably won't work. There are lower level paramiko commands on the channel itself that give you more control - see how the SSHClient.exec_command method is implemented for all the gory details.
I had the same problem trying to make an interactive ssh session using ssh, a fork of Paramiko.
I dug around and found this article:
Updated link (last version before the link generated a 404): http://web.archive.org/web/20170912043432/http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/
To continue your example you could do
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
ssh_stdin.write('password\n')
ssh_stdin.flush()
output = ssh_stdout.read()
The article goes more in depth, describing a fully interactive shell around exec_command. I found this a lot easier to use than the examples in the source.
Original link: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/
You need Pexpect to get the best of both worlds (expect and ssh wrappers).
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server_IP,22,username, password)
stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol-CXC_173_6456-R32A01/uecontrol.sh -host localhost ')
alldata = ""
while not stdout.channel.exit_status_ready():
solo_line = ""
# Print stdout data when available
if stdout.channel.recv_ready():
# Retrieve the first 1024 bytes
solo_line = stdout.channel.recv(1024)
alldata += solo_line
if(cmp(solo_line,'uec> ') ==0 ): #Change Conditionals to your code here
if num_of_input == 0 :
data_buffer = ""
for cmd in commandList :
#print cmd
stdin.channel.send(cmd) # send input commmand 1
num_of_input += 1
if num_of_input == 1 :
stdin.channel.send('q \n') # send input commmand 2 , in my code is exit the interactive session, the connect will close.
num_of_input += 1
print alldata
ssh.close()
Why the stdout.read() will hang if use dierectly without checking stdout.channel.recv_ready(): in while stdout.channel.exit_status_ready():
For my case ,after run command on remote server , the session is waiting for user input , after input 'q' ,it will close the connection .
But before inputting 'q' , the stdout.read() will waiting for EOF,seems this methord does not works if buffer is larger .
I tried stdout.read(1) in while , it works
I tried stdout.readline() in while , it works also.
stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol')
stdout.read() will hang
I'm not familiar with paramiko, but this may work:
ssh_stdin.write('input value')
ssh_stdin.flush()
For information on stdin:
http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin
Take a look at example and do in similar way
(sorce from http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/):
ssh.connect('127.0.0.1', username='jesse',
password='lol')
stdin, stdout, stderr = ssh.exec_command(
"sudo dmesg")
stdin.write('lol\n')
stdin.flush()
data = stdout.read.splitlines()
for line in data:
if line.split(':')[0] == 'AirPort':
print line
You can use this method to send whatever confirmation message you want like "OK" or the password. This is my solution with an example:
def SpecialConfirmation(command, message, reply):
net_connect.config_mode() # To enter config mode
net_connect.remote_conn.sendall(str(command)+'\n' )
time.sleep(3)
output = net_connect.remote_conn.recv(65535).decode('utf-8')
ReplyAppend=''
if str(message) in output:
for i in range(0,(len(reply))):
ReplyAppend+=str(reply[i])+'\n'
net_connect.remote_conn.sendall(ReplyAppend)
output = net_connect.remote_conn.recv(65535).decode('utf-8')
print (output)
return output
CryptoPkiEnroll=['','','no','no','yes']
output=SpecialConfirmation ('crypto pki enroll TCA','Password' , CryptoPkiEnroll )
print (output)