繁体   English   中英

在python中执行bash脚本

[英]Executing a bash script in python

我创建了一个Expect脚本,该脚本在执行时将ssh连接到服务器上并执行一系列命令。 伪代码如下所示:

#!/usr/bin/expect
spawn ssh usr@myip
expect "password:"
send "mypassword\n";
send "./mycommand1\r"
send "./mycommand2\r"
interact

从bash shell($ ./myscript.txt)执行时,代码可以正常执行。 我现在想做的是在python文件中有一行,以与bash shell相同的方式运行脚本中的命令。 伪代码如下所示:

import subprocess
def runmyscript():
    subprocess.call("myscript.txt", executable="expect", shell=True)
def main():
    run = runmyscript():
if __name__ == '__main__': main()   

我已经将myscript.txt脚本文件放置在与runmyscript.py文件相同的目录中,但是当我运行python文件时,却收到错误消息:

WindowsError: [Error 2] The system cannot find the file specified

我已经阅读了python.org站点上文档 ,但无济于事。 有没有人可以从.py代码中执行bash脚本的狡猾解决方案?

解决方案:此代码对我有用。

child = subprocess.Popen(['bash', '-c', './myscript.txt'], stdout = subprocess.PIPE)

使用此代码来调用Expect文件以ssh并将命令从.py文件发送到服务器-如果您在将pycrypto / paramiko内置到计算机上时遇到问题,这是有用的解决方案。

这是您的Expect脚本的python实现:

import paramiko

user = "user"
pass = "pass"
host = "host"

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, port=22, username=user, password=pass)
client.exec_command("./mycommand1")
client.exec_command("./mycommand2")
client.close()

您可以使用pexpect( http://www.noah.org/wiki/pexpect

这是一个示例函数,处理通过ssh远程执行命令时可能遇到的许多情况。

import pexpect 

## Cleanly handle a variety of scenarios that can occur when ssh or scp-ing to an ip:port
# amongst them are:
# 
# (1) key has not been setup
# (2) key has changed since last time
# (3) command was executed (check exit status and output) 
#
# @param cmdLine  The "scp" or "ssh" command-line
# @param mtimeout The millisecond timeout to wait for the child process to return
# @param log      The log to record events to if necessary
def cleanlyHandleSecureCmd(cmdLine, mtimeout = None, log = None):
  status = -1
  output = None

  if mtimeout == None:
    mtimeout = 60 * 1000

  if cmdLine != None and ('scp' in cmdLine or 'ssh' in cmdLine):
    # Scenarios for ssh include: (1) key not setup (2) key changed (3) remote cmd was executed (check exit status)
    scenarios = ['Are you sure you want to continue connecting', '@@@@@@@@@@@@', EOF]
    child     = spawn(cmdLine, timeout = mtimeout)
    scenario  = child.expect(scenarios)

    if scenario == 0:
      # (1) key not setup ==> say 'yes' and allow child process to continue
      child.sendline('yes')

      scenario = child.expect(scenarios)

    if scenario == 1:
      if log != None:
        # (2) key changed ==> warn the user in the log that this was encountered
        log.write('WARNING (' + cmdLine  + '): ssh command encountered man-in-the-middle scenario! Please investigate.')

      lines    = child.readlines()
      scenario = child.expect([EOF])

      child.close()
    else:
      # (3) remote cmd was executed ==> check the exit status and log any errors
      child.close()

      status = child.exitstatus
      output = child.before
      output = sub('\r\n', '\n', output)  # Do not be pedantic about end-of-line chars 
      output = sub('\n$',  '',   output)  # Ignore any trailing newline that is present

      if status == None:
        status = child.status

      if status != 0 and log != None:
        log.error('Error executing command \'' + str(cmdLine) + '\' gave status of ' + str(status) + ' and output: ' + str(output))
  else:
    if log != None:
      log.error('Command-line must contain either ssh or scp: ' + str(cmdLine))

  return (status, output)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM