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
When executing a command in paramiko, it always resets the session when you run exec_command. I want to able to execute sudo or su and still have those privileges when I run another exec_command. Another example would be trying to exec_command("cd /") and then run exec_command again and have it be in the root directory. I know you can do something like exec_command("cd /; ls -l"), but I need to do it in separate function calls.
在paramiko中执行命令时,它总是在运行exec_command时重置会话。我希望能够执行sudo或su,并且当我运行另一个exec_command时仍然具有这些权限。另一个例子是尝试exec_command(“cd /”)然后再次运行exec_command并让它在根目录中。我知道你可以做类似exec_command(“cd /; ls -l”)的东西,但我需要在单独的函数调用中完成。
5 个解决方案
#1
35
Non-Interactive use cases
非交互式用例
This is a non-interactive example... it sends cd tmp
, ls
and then exit
.
这是一个非交互式的例子......它发送cd tmp,ls然后退出。
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()
Interactive use cases
If you have an interactive use case , this answer won't help... I personally would use pexpect
or exscript
for interactive sessions.
交互式用例如果您有一个交互式用例,这个答案将无济于事......我个人会使用pexpect或exscript进行交互式会话。
#2
19
Strictly speaking, you can't. According to the ssh spec:
严格来说,你不能。根据ssh规范:
A session is a remote execution of a program. The program may be a shell, an application, a system command, or some built-in subsystem.
会话是程序的远程执行。该程序可以是shell,应用程序,系统命令或某些内置子系统。
This means that, once the command has executed, the session is finished. You cannot execute multiple commands in one session. What you CAN do, however, is starting a remote shell (== one command), and interact with that shell through stdin etc... (think of executing a python script vs. running the interactive interpreter)
这意味着,一旦命令执行,会话就完成了。您无法在一个会话中执行多个命令。但是,您可以做的是启动远程shell(==一个命令),并通过stdin等与该shell进行交互...(想想执行python脚本与运行交互式解释器)
#3
6
Try creating a command string separated by \n
character. It worked for me. For. e.g. ssh.exec_command("command_1 \n command_2 \n command_3")
尝试创建由\ n字符分隔的命令字符串。它对我有用。对于。例如ssh.exec_command(“command_1 \ n command_2 \ n command_3”)
#4
3
You can do that by invoking shell on the client and sending commands. Please refer here
The page has code for python 3.5. I have modified the code a bit to work for pythin 2.7. Adding code here for reference
您可以通过在客户端上调用shell并发送命令来实现。请参考这里该页面包含python 3.5的代码。我已经修改了一些代码以适用于pythin 2.7。在此添加代码以供参考
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()
#5
2
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()
#1
35
Non-Interactive use cases
非交互式用例
This is a non-interactive example... it sends cd tmp
, ls
and then exit
.
这是一个非交互式的例子......它发送cd tmp,ls然后退出。
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()
Interactive use cases
If you have an interactive use case , this answer won't help... I personally would use pexpect
or exscript
for interactive sessions.
交互式用例如果您有一个交互式用例,这个答案将无济于事......我个人会使用pexpect或exscript进行交互式会话。
#2
19
Strictly speaking, you can't. According to the ssh spec:
严格来说,你不能。根据ssh规范:
A session is a remote execution of a program. The program may be a shell, an application, a system command, or some built-in subsystem.
会话是程序的远程执行。该程序可以是shell,应用程序,系统命令或某些内置子系统。
This means that, once the command has executed, the session is finished. You cannot execute multiple commands in one session. What you CAN do, however, is starting a remote shell (== one command), and interact with that shell through stdin etc... (think of executing a python script vs. running the interactive interpreter)
这意味着,一旦命令执行,会话就完成了。您无法在一个会话中执行多个命令。但是,您可以做的是启动远程shell(==一个命令),并通过stdin等与该shell进行交互...(想想执行python脚本与运行交互式解释器)
#3
6
Try creating a command string separated by \n
character. It worked for me. For. e.g. ssh.exec_command("command_1 \n command_2 \n command_3")
尝试创建由\ n字符分隔的命令字符串。它对我有用。对于。例如ssh.exec_command(“command_1 \ n command_2 \ n command_3”)
#4
3
You can do that by invoking shell on the client and sending commands. Please refer here
The page has code for python 3.5. I have modified the code a bit to work for pythin 2.7. Adding code here for reference
您可以通过在客户端上调用shell并发送命令来实现。请参考这里该页面包含python 3.5的代码。我已经修改了一些代码以适用于pythin 2.7。在此添加代码以供参考
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()
#5
2
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()