在python中执行bash脚本
我已经创建了一个expect脚本,当执行该脚本时,ssh将进入服务器并执行一系列命令。伪代码如下所示:在python中执行bash脚本,python,bash,popen,expect,Python,Bash,Popen,Expect,我已经创建了一个expect脚本,当执行该脚本时,ssh将进入服务器并执行一系列命令。伪代码如下所示: #!/usr/bin/expect spawn ssh usr@myip expect "password:" send "mypassword\n"; send "./mycommand1\r" send "./mycommand2\r" interact import subprocess def runmyscript(): subprocess.call("myscript.
#!/usr/bin/expect
spawn ssh usr@myip
expect "password:"
send "mypassword\n";
send "./mycommand1\r"
send "./mycommand2\r"
interact
import subprocess
def runmyscript():
subprocess.call("myscript.txt", executable="expect", shell=True)
def main():
run = runmyscript():
if __name__ == '__main__': main()
从bash shell($./myscript.txt)执行时,代码执行良好。我现在想做的是在python文件中有一行代码,它以与bashshell相同的方式在脚本中运行命令。伪代码如下所示:
#!/usr/bin/expect
spawn ssh usr@myip
expect "password:"
send "mypassword\n";
send "./mycommand1\r"
send "./mycommand2\r"
interact
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
我通读了这本书,但没有用。有没有人能从.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()
下面是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()
下面是一个示例函数,用于处理通过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)
您可以使用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)
好的,您可以运行/usr/bin/expect myscript.txt,但也可以用python编写整个expect脚本(我建议这样做),请参见lkjoel-如何从python重写myscript.txt中的命令行?用python编写expect脚本当然更可取——这样可以更容易地添加命令。user946850的链接对于ssh部分很有用。就此而言,什么python命令可以“运行/usr/bin/expect myscript.txt”?谢谢您的帮助。@gortron-您可以使用pexepect模块用python编写它。最好在你的情况下使用paramiko。此外,该脚本根本不是bash。您可以运行/usr/bin/expect myscript.txt,但也可以用python编写整个expect脚本(我建议这样做),请参见lkjoel-如何从python重写myscript.txt中的命令行?用python编写expect脚本当然更可取——这样可以更容易地添加命令。user946850的链接对于ssh部分很有用。就此而言,什么python命令可以“运行/usr/bin/expect myscript.txt”?谢谢您的帮助。@gortron-您可以使用pexepect模块用python编写它。最好在你的情况下使用paramiko。而且,该脚本根本不是bash,事实证明,在我的Python构建中安装Paramiko非常困难。我将继续努力寻找子流程解决方案,并在找到它后将其发布到这里。事实证明,在我的Python构建中安装Paramiko非常困难。我将继续努力寻找子流程解决方案,并在找到它后将其发布到这里。