我一直试图在另一个python脚本中运行脚本而没有运气。
我试图运行的脚本是garminbackup.py,可以在以下repo中找到。
https://github.com/petergardfjall/garminexport
当您从命令行运行此脚本时,它会要求您提供一些信息,用户名,保存文件的位置等等...
command = 'python garminbackup.py --backup-dir=Name email --format tcx'
然后它要求输入密码,一旦输入密码,就开始将garmin文件下载到提供的目录中。我的目标是创建一个程序,它循环遍历多个帐户并更新每个文件夹中的数据。
我的问题是我似乎无法在python中获得子进程模块来实现这一点。
我尝试了以下命令但没有运气。它似乎卡在输入密码输入屏幕上,并没有做任何其他事情。
import subprocess,shlex
from subprocess import PIPE,call
import os
p = subprocess.Popen(command,stdout=subprocess.PIPE,stdin=subprocess.PIPE,shell=True)
p.stdin.write("password\n")
p.wait()
我搜索了几个小时没有运气。任何帮助表示赞赏。
答案 0 :(得分:0)
尽管OP通过使用--password
选项解决了该问题,但其他人可能会偶然遇到相同的问题,并且已经pointed out by HuStmpHrr的情况下,在命令行中传递密码不是一个好主意。
被调用的脚本,在这种情况下,garminbackup.py
使用getpass。正如文档中所暗示的,getpass的实现比仅仅阅读stdin更复杂:
[...]在Unix上,提示被写入类似文件的对象流中。 流默认为控制终端(/ dev / tty),或者 sys.stderr不可用(在Windows上将忽略此参数)。
如果没有无回声输入,getpass()将退回到打印 警告消息流并从sys.stdin中读取并发出 GetPass警告。
我们可以模拟一个虚拟终端,但是如果没有一个库,那就太复杂了(请参阅下一章)。
另一种方法是摆脱存在终端的信息(“如果无回声输入不可用”)。事实证明,这比我想象的要难,通常以cat | command | cat
的身份运行命令应该摆脱tty检测,但是getpass要么变得聪明要么就变得无知,无法改变其行为。
已经mentioned by LohmarASHAR,如果可以使用pexpect(pip install pexpect
),则应该使用。正是为此而做的,它将涵盖所有极端情况。
例如:
child = pexpect.spawn('scp foo user@example.com:.') child.expect('Password:') child.sendline(mypassword)
此功能甚至适用于要求输入密码或其他输入的命令 常规stdio流之外。例如,ssh读取输入 直接从绕过标准输入的TTY设备开始。
使用OP的示例,但要使用pexpect:
#!/usr/bin/env python
import pexpect
command = 'python garminbackup.py --backup-dir=Name email --format tcx'
p = pexpect.spawn(command) # instead of subprocess.Popen
p.expect(":") # This is waiting for the prompt "Enter password:", but I rather only use ":" to cope with internationalisation issues
p.sendline("password")
print p.read() # Output the sub-processes output
p.wait()