python 外部程序 交互_如何与Python中的另一个程序进行交互?

1586010002-jmsa.png

I want to write a Python script that runs another program, reading the output of the other program and manipulating it. The problem is that this program prompts for a password, and I cannot figure out how to supply it automatically. (For the purposes of this script, it really does not matter if the password is stored in plain-text in the script itself.) What I want to do is something like:

os.system('echo someinput | /var/local/bin/someprogram')

Which results in someprogram giving me the unwanted password prompt, and also doesn't give me the program's output as the return value. Tragically, the program does not have a way to bypass this prompt.

Unfortunately, I also have some restrictions as to how I can go about solving this problem. First, I'm stuck with Python 2.3 (so I cannot use the subprocess module). Second, I cannot install any new modules, (so no pexpect). Fortunately, it doesn't have to be particularly portable, so a Linux-only solution is fine.

I've been trying to figure out the pty module, since it looks like it offers what I need, but after spending hours wrestling with it, I just cannot figure out how to get it to work the way I need it to.

解决方案

I had some similar problems with terminal-based interprocess communication that didn't seem to be solvable using popen (et al.). I ended up learning how to use pty by reading the source of pexpect, which contains examples of how (and comments of why) to get pty to jump through the necessary hoops.

Depending on your needs, of course, you could also just use pexpect!

Here's the meat of what I used in my own project. Note that I'm not checking to see whether the child process terminates; the script was intended to run as a daemon managing a long-running Java process, so I never had to deal with status codes. Hopefully, this will get you most of what you need, however.

import os

import pty

import select

import termios

child_pid, child_fd = pty.fork()

if not child_pid: # child process

os.execv("/path/to/command", ["command", "arg1", "arg2"])

# disable echo

attr = termios.tcgetattr(child_fd)

attr[3] = attr[3] & ~termios.ECHO

termios.tcsetattr(child_fd, termios.TCSANOW, attr)

while True:

# check whether child terminal has output to read

ready, _, _ = select.select([child_fd], [], [])

if child_fd in ready:

output = []

try:

while True:

s = os.read(child_fd, 1)

# EOF or EOL

if not s or s == "\n":

break

# don't store carriage returns (no universal line endings)

if not s == "\r":

output.append(s)

except OSError: # this signals EOF on some platforms

pass

if output.find("Enter password:") > -1:

os.write(child_fd, "password")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值