I have tried with subprocess and sshpass to execute remote command. Here is my code to execute remote command using subprocess..
import subprocess
import sys
HOST="192.168.20.175"
COMMAND="cat /proc/meminfo | grep MemTotal"
ssh = subprocess.Popen(["sshpass", "-p", "unlock123",
"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
print "Return Code - %s" % ssh.returncode
However,
returncode returns None
Now I want to run following loop command on remote machine
"echo"; while true; do ps -p 1820 -o %cpu,%mem | grep -v CPU >> /tmp/proc_out.log;
I want to start the command on remote machine and don't want to wait for the command to complete.
Once the command is fired, get the pid of the command
Kill the process after some time whenever required.
Is there any possible solution for this?
Related
I am developing a backup python program, one of the modules makes a rsync backup of a remote folder into my local device.
This is the part of the code where I have the problem:
try:
process = subprocess.Popen(
['sshpass',
'-p',
password,
'rsync',
'-avz',
'-e',
'ssh -o StrictHostKeyChecking=no',
'-p',
port,
'{}#{}:{}'.format(user, host, folder),
dest_folder],
stdout=subprocess.PIPE
)
output = process.communicate()[0]
if int(process.returncode) != 0:
print('Command failed. Return code : {}'.format(process.returncode))
exit(1)
return output
except Exception as e:
print(e)
exit(1)
The shown error is:
Unexpected remote arg: debian#12.345.67.89:/folder1/folder2/
rsync error: syntax or usage error (code 1) at main.c(1372) [sender=3.1.3]
Command failed. Return code : 1
I believe that the problem is with the array in Popen. If I run the single command in bash I rsync successfully.
What should I change from subprocess.Popen array?
This is caused by -p flag being consumed by rsync rather than ssh, and as such the destination effectively is set to port.
The -e argument of rsync takes exactly one parameter. That means that only 'ssh -o StrictHostKeyChecking=no' will be passed as an argument. Unluckily for you, -p is an actual flag of rsync, and as such it's processed without error. It means 'preserve permissions'. This means that rather than setting port to use with ssh, you're passing a flag to rsync, and the next parameter gets interpreted as a destination.
You can fix it by changing
'ssh -o StrictHostKeyChecking=no',
'-p',
port,
to simply
'ssh -o StrictHostKeyChecking=no -p {}'.format(port),
I am trying to use the call below to shut down my system, but I would like it to work on all major OS distro's. Is there a catch all shutdown command?
import os
os.system("shutdown /s /t 1")
Is there any other way to shutdown a machine remotely through python code?
For managing nodes remotely, ansible is a very nice tool, with gather facts you can get the current node os, then conditionally shut down accordingly.
Following function provides portable way of sending commands to remote host:
def run_shell_remote_command(remote_host, remote_cmd, pem_file=None, ignore_errors=False):
remote_cmd = remote_cmd.split(' ')
cmd = [SSH_PATH, '-o ConnectTimeout=30', '-o BatchMode=yes', '-o StrictHostKeyChecking=no']
if pem_file:
cmd.extend(['-i', pem_file])
cmd.extend([remote_host] + remote_cmd)
print(f"SSH CMD: {cmd}")
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
if not ignore_errors:
raise RuntimeError("%r failed, status code %s stdout %r stderr %r" % (
remote_cmd, p.returncode, stdout, stderr))
return stdout.strip() # This is the stdout from the shell command
That way you can run any command on remote host, which are supported by remote OS.
I have written a below script to do ssh and providing password .But it still waits for password prompt while running . Searched through many such questions on stack overflow, Everyone suggesting to use paramiko or pexpect but I can not use this as this script has to be run by many people on different machines and can not ask everyone to install these libraries first
Looking for a solution without using such libraries
import subprocess
import sys
HOST="lab#xxxx"
COMMAND="pwd"
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND], shell=False, stdout=subprocess.PIPE, stdin = subprocess.PIPE, stderr=subprocess.PIPE)
ssh.stdin.write('lab\n')
ssh.stdin.flush()
result = ssh.stdout.readlines()
if result == []:
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
else:
print result
~
I have requirement to connect to one remote host and perform set of operation using python script like grep for files and check whether DB is running or not .
This what sample code i got
import subprocess
import sys
HOST="yyy03xxx.us.kkk.com"
# 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
Please suggest how can i modify this code to multiple operation
I need to ssh into the server and execute few commands and process the response using subprocess. Here's my code
command = 'ssh -t -t buildMachine.X.lan; sudo su - buildbot ; build-set sets/set123'
print "submitting command"
result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
print "got response"
response,err = result.communicate()
print response
This is getting stuck. I have seen other threads talking about passing a list instead of string to subprocess and removing shell=True.. I did that too but didn't work.
Ultimately I need the result of last command i.e. build-set in order to extract some information out of it.. help?
I figured the solution by using univerio's comment
The command needs to be
command = 'ssh -t -t buildMachine.X.lan \'sudo su - buildbot \'build-set sets/set123\'\''
Individual commands are like argument to previous command. This works.