def exec_command(self, command, bufsize=-1):
#print "Executing Command: "+command
chan = self._transport.open_session()
chan.exec_command(command)
stdin = chan.makefile('wb', bufsize)
stdout = chan.makefile('rb', bufsize)
stderr = chan.makefile_stderr('rb', bufsize)
return stdin, stdout, stderr
Lors de l'exécution d'une commande dans paramiko, elle réinitialise toujours la session lorsque vous exécutez exec_command. Je veux pouvoir exécuter Sudo ou su et avoir toujours ces privilèges lorsque j'exécute une autre commande exec_command. Un autre exemple serait d'essayer d'exec_command ("cd /"), puis d'exécuter à nouveau exec_command et de le placer dans le répertoire racine. Je sais que vous pouvez faire quelque chose comme exec_command ("cd /; ls -l"), mais je dois le faire dans des appels de fonction séparés.
Cas d'utilisation non interactifs
Ceci est un exemple non interactif ... il envoie cd tmp
, ls
puis exit
.
import sys
sys.stderr = open('/dev/null') # Silence silly warnings from paramiko
import paramiko as pm
sys.stderr = sys.__stderr__
import os
class AllowAllKeys(pm.MissingHostKeyPolicy):
def missing_Host_key(self, client, hostname, key):
return
Host = '127.0.0.1'
USER = ''
PASSWORD = ''
client = pm.SSHClient()
client.load_system_Host_keys()
client.load_Host_keys(os.path.expanduser('~/.ssh/known_hosts'))
client.set_missing_Host_key_policy(AllowAllKeys())
client.connect(Host, username=USER, password=PASSWORD)
channel = client.invoke_Shell()
stdin = channel.makefile('wb')
stdout = channel.makefile('rb')
stdin.write('''
cd tmp
ls
exit
''')
print stdout.read()
stdout.close()
stdin.close()
client.close()
Cas d'utilisation interactifs
Si vous avez un cas d'utilisation interactif, cette réponse n'aidera pas ... Personnellement, j'utiliserais pexpect
ou exscript
pour des sessions interactives.
À strictement parler, vous ne pouvez pas. Selon la spécification ssh:
Une session est une exécution à distance d'un programme. Le programme peut être un shell, une application, une commande système ou un sous-système intégré.
Cela signifie qu'une fois la commande exécutée, la session est terminée. Vous ne pouvez pas exécuter plusieurs commandes en une seule session. Ce que vous POUVEZ faire, cependant, est de démarrer un Shell distant (== une commande), et d'interagir avec ce Shell via stdin etc ... (pensez à exécuter un script python vs exécuter le interprète interactif)
Essayez de créer une chaîne de commande séparée par le caractère \n
. Ça a marché pour moi. Pour. par exemple. ssh.exec_command("command_1 \n command_2 \n command_3")
Vous pouvez le faire en appelant Shell sur le client et en envoyant des commandes. Veuillez vous référer ici
La page contient du code pour python 3.5. J'ai un peu modifié le code pour qu'il fonctionne avec pythin 2.7. Ajouter du code ici pour référence
import threading, paramiko
strdata=''
fulldata=''
class ssh:
Shell = None
client = None
transport = None
def __init__(self, address, username, password):
print("Connecting to server on ip", str(address) + ".")
self.client = paramiko.client.SSHClient()
self.client.set_missing_Host_key_policy(paramiko.client.AutoAddPolicy())
self.client.connect(address, username=username, password=password, look_for_keys=False)
self.transport = paramiko.Transport((address, 22))
self.transport.connect(username=username, password=password)
thread = threading.Thread(target=self.process)
thread.daemon = True
thread.start()
def close_connection(self):
if(self.client != None):
self.client.close()
self.transport.close()
def open_Shell(self):
self.Shell = self.client.invoke_Shell()
def send_Shell(self, command):
if(self.Shell):
self.Shell.send(command + "\n")
else:
print("Shell not opened.")
def process(self):
global strdata, fulldata
while True:
# Print data when available
if self.Shell is not None and self.Shell.recv_ready():
alldata = self.Shell.recv(1024)
while self.Shell.recv_ready():
alldata += self.Shell.recv(1024)
strdata = strdata + str(alldata)
fulldata = fulldata + str(alldata)
strdata = self.print_lines(strdata) # print all received data except last line
def print_lines(self, data):
last_line = data
if '\n' in data:
lines = data.splitlines()
for i in range(0, len(lines)-1):
print(lines[i])
last_line = lines[len(lines) - 1]
if data.endswith('\n'):
print(last_line)
last_line = ''
return last_line
sshUsername = "SSH USERNAME"
sshPassword = "SSH PASSWORD"
sshServer = "SSH SERVER ADDRESS"
connection = ssh(sshServer, sshUsername, sshPassword)
connection.open_Shell()
connection.send_Shell('cmd1')
connection.send_Shell('cmd2')
connection.send_Shell('cmd3')
time.sleep(10)
print(strdata) # print the last line of received data
print('==========================')
print(fulldata) # This contains the complete data received.
print('==========================')
connection.close_connection()
cmd = 'ls /home/dir'
self.ssh_stdin, self.ssh_stdout, self.ssh_stderr = self.ssh.exec_command(cmd)
print self.ssh_stdout.read()
cmd2 = 'cat /home/dir/test.log'
self.ssh_stdin2, self.ssh_stdout2, self.ssh_stderr2 = self.ssh.exec_command(cmd2)
print self.ssh_stdout2.read()