Reputation: 433
I have a python script which is supposed to ssh in to a client and execute a bash from the client. As a test scenario I am using just 1 machine to connect but the objective is to connect to several clients and execute bash scripts from those machines.
My Python code:
import os
import subprocess
import time
def ssh_login_execute():
if device['PWD'] != "":
run=('sshpass -p %s ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t -p %s %s@%s' % (device['PWD'], device['PORT'], device['USER'], device['IP']))
else:
run=('ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t -p %s %s@%s' % (device['PORT'], device['USER'], device['IP']))
cmd = ('cd %s' % (script_path))
run2=run.split()
run2.append(cmd)
t=subprocess.Popen(run2, stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'))
print "I am in 192.168.1.97"
execute_tg()
return t
def execute_tg():
path = "/home/"
os.chdir(path)
print os.getcwd()
cmd=("sh my_script.sh")
t=subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if __name__ == "__main__":
device = {}
device['PORT']=22
device['PWD']= "abcd"
device['USER']= "root"
device['IP']= "192.168.1.97"
script_path= "/home/"
ssh_login_execute()
On running the code "python script.py", I see output as:
I am in 192.168.1.97
/home/
Output is sh: 0: Can't open my_script.sh
Although the "my_script.sh" is in /home directory in 192.168.1.97. How do I get rid of this issue and at the same time make it scalable to ssh to multiple clients and execute bash.
Upvotes: 1
Views: 18147
Reputation: 309
Actually sshpass executes ssh command/connection in a single go. Once the remote query is executed through subprocess.Popen() your program control will be back to local machine in the next line. And your program will give error "Can't open my_script.sh" because your script is not on local machine whereas it is on remote machine.
My suggestion is to make the full sshpass command with what to execute in a single program varibale (in your case 'run2' variable) and pass it to subprocess.Popen() in single go. Modified code is as below:
import os
import subprocess
import time
def ssh_login_execute():
if device['PWD'] != "":
run=('sshpass -p %s ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t -p %s %s@%s' % (device['PWD'], device['PORT'], device['USER'], device['IP']))
else:
run=('ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t -p %s %s@%s' % (device['PORT'], device['USER'], device['IP']))
cmd = ('sh /%s/%s' % (script_path,'my_script.sh'))
run2=run.split()
run2.append(cmd)
t=subprocess.Popen(run2, stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'))
print "I am in 192.168.1.97" # HERE YOU ASSUMED THAT YOU ARE IN REMOTE MACHINE BUT ACTUALLY YOU ARE IN LOCAL MACHINE ONLY
return t
if __name__ == "__main__":
device = {}
device['PORT']=22
device['PWD']= "abcd"
device['USER']= "root"
device['IP']= "192.168.1.97"
script_path= "/home/"
ssh_login_execute()
Upvotes: 0
Reputation: 94
Here is an example utilizing the paramiko module and using the getpass module:
#!/usr/bin/python
import paramiko
import getpass
class Remote():
def __init__(self, hostfile, username, commands):
self.hostfile = hostfile
self.username = username
self.commands = commands
def execute(self):
client = paramiko.SSHClient()
client.load_system_host_keys()
##########################################################
# just in case it does not recognize the known_host keys
# in the known_hosts file
##########################################################
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.password = getpass.getpass("Password: ")
for i in self.hostfile.readlines():
print("Connecting to..." + i)
client.connect(i.strip(), 22, self.username, self.password)
stdin, stdout, stderr = client.exec_command(self.commands)
for t in stdout.readlines():
print(t.strip())
for t in stderr.readlines():
print(t.strip())
#--------------------------------------------------------
commands="""
echo "##################################################";
hostname;
echo "##################################################";
uname -a;
echo "##################################################";
dmidecode -t bios
"""
#---------------------------------------------------------
username = raw_input("Username: ")
hostfile = open('hosts')
a = Remote(hostfile, username, commands)
a.execute()
Upvotes: 1
Reputation: 75478
Your script my_script.sh
is probably not in /home/
as expected in the code.
path = "/home/"
os.chdir(path)
print os.getcwd()
cmd=("sh my_script.sh")
Also it should print the current directory as well with print os.getcwd()
. You should change those values based on the real location of your script.
Upvotes: 2
Reputation: 15996
Your "home" directory is usually something like /home/<username>
or perhaps /users/<username>
. In general shells will generally accept ~
as a synonym for the path to your home directory. Does this work instead:
cmd=("sh ~/my_script.sh")
Upvotes: 0