我正在编写一个脚本来自动化Python中的一些命令行命令.此刻我正在打电话:
cmd = "some unix command"
retcode = subprocess.call(cmd,shell=True)
Run Code Online (Sandbox Code Playgroud)
但是我需要在远程计算机上运行一些命令.手动,我会使用ssh登录然后运行命令.我如何在Python中自动执行此操作?我需要使用(已知的)密码登录到远程机器,所以我不能只使用cmd = ssh user@remotehost
,我想知道是否有一个我应该使用的模块?
sha*_*pan 176
我会把你推荐给paramiko
看到这个问题
ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)
Run Code Online (Sandbox Code Playgroud)
pow*_*rox 45
或者你可以使用commands.getstatusoutput:
commands.getstatusoutput("ssh machine 1 'your script'")
Run Code Online (Sandbox Code Playgroud)
我广泛使用它,效果很好.
在Python 2.6+中,使用subprocess.check_output
.
Ron*_*acc 43
把事情简单化。不需要库。
import subprocess
subprocess.Popen("ssh {user}@{host} {cmd}".format(user=user, host=host, cmd='ls -l'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
Run Code Online (Sandbox Code Playgroud)
Mic*_*son 16
我发现paramiko有点太低级了,而且Fabric不太适合用作库,所以我把我自己的库叫做spur,使用paramiko来实现一个稍微好一点的界面:
import spur
shell = spur.SshShell(hostname="localhost", username="bob", password="password1")
result = shell.run(["echo", "-n", "hello"])
print result.output # prints hello
Run Code Online (Sandbox Code Playgroud)
如果你需要在shell中运行:
shell.run(["sh", "-c", "echo -n hello"])
Run Code Online (Sandbox Code Playgroud)
Ped*_*ito 11
接受的答案对我不起作用,这是我使用的:
import paramiko
import os
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# ssh.load_system_host_keys()
ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
ssh.connect("d.d.d.d", username="user", password="pass", port=22222)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("ls -alrt")
exit_code = ssh_stdout.channel.recv_exit_status() # handles async exit error
for line in ssh_stdout:
print(line.strip())
Run Code Online (Sandbox Code Playgroud)
total 44
-rw-r--r--. 1 root root 129 Dec 28 2013 .tcshrc
-rw-r--r--. 1 root root 100 Dec 28 2013 .cshrc
-rw-r--r--. 1 root root 176 Dec 28 2013 .bashrc
...
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用sshpass:
import subprocess
cmd = """ sshpass -p "myPas$" ssh user@d.d.d.d -p 12345 'my command; exit' """
print( subprocess.getoutput(cmd) )
Run Code Online (Sandbox Code Playgroud)
参考:
笔记:
ssh root@ip
) 手动连接到远程系统至少一次并接受公钥,这很多时候是无法使用paramiko
其他自动ssh
脚本进行连接的原因。添加额外的行后,paramiko终于为我工作了,这真的很重要(第 3 行):
import paramiko
p = paramiko.SSHClient()
p.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # This script doesn't work for me unless this line is added!
p.connect("server", port=22, username="username", password="password")
stdin, stdout, stderr = p.exec_command("your command")
opt = stdout.readlines()
opt = "".join(opt)
print(opt)
Run Code Online (Sandbox Code Playgroud)
确保已安装 paramiko 包。解决方案的原始来源:Source
所有人都已经说过(推荐)使用paramiko,我只是共享一个python代码(API可能会说),它允许你一次执行多个命令.
在不同节点上执行命令: Commands().run_cmd(host_ip, list_of_commands)
您将看到一个TODO,如果任何命令无法执行,我会一直停止执行,我不知道该怎么做.请分享你的知识
#!/usr/bin/python
import os
import sys
import select
import paramiko
import time
class Commands:
def __init__(self, retry_time=0):
self.retry_time = retry_time
pass
def run_cmd(self, host_ip, cmd_list):
i = 0
while True:
# print("Trying to connect to %s (%i/%i)" % (self.host, i, self.retry_time))
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host_ip)
break
except paramiko.AuthenticationException:
print("Authentication failed when connecting to %s" % host_ip)
sys.exit(1)
except:
print("Could not SSH to %s, waiting for it to start" % host_ip)
i += 1
time.sleep(2)
# If we could not connect within time limit
if i >= self.retry_time:
print("Could not connect to %s. Giving up" % host_ip)
sys.exit(1)
# After connection is successful
# Send the command
for command in cmd_list:
# print command
print "> " + command
# execute commands
stdin, stdout, stderr = ssh.exec_command(command)
# TODO() : if an error is thrown, stop further rules and revert back changes
# Wait for the command to terminate
while not stdout.channel.exit_status_ready():
# Only print data if there is data to read in the channel
if stdout.channel.recv_ready():
rl, wl, xl = select.select([ stdout.channel ], [ ], [ ], 0.0)
if len(rl) > 0:
tmp = stdout.channel.recv(1024)
output = tmp.decode()
print output
# Close SSH connection
ssh.close()
return
def main(args=None):
if args is None:
print "arguments expected"
else:
# args = {'<ip_address>', <list_of_commands>}
mytest = Commands()
mytest.run_cmd(host_ip=args[0], cmd_list=args[1])
return
if __name__ == "__main__":
main(sys.argv[1:])
Run Code Online (Sandbox Code Playgroud)
谢谢!
归档时间: |
|
查看次数: |
376523 次 |
最近记录: |