首先让我说,我知道使用 subprocess 模块会更好,但我正在编辑其他人的代码,并且我正在尝试进行尽可能少的更改,其中包括避免导入任何新模块。因此,如果可能的话,我想坚持使用当前导入的模块(操作系统、系统和路径)。
代码当前(在一个名为 postfix-to-mailman.py 的文件中,你们中的一些人可能熟悉):
if local in ('postmaster', 'abuse', 'mailer-daemon'):
os.execv("/usr/sbin/sendmail", ("/usr/sbin/sendmail", 'first@place.com'))
sys.exit(0)
这很好用(尽管我认为 sys.exit(0) 可能永远不会被调用,因此是不必要的)。
我相信这会通过调用 /usr/sbin/sendmail 将当前进程替换为传递参数 /usr/sbin/sendmail(对于 argv[0] 即本身)和“someaddress@someplace.com”,然后传递当前进程 - 包括 sys.stdin 中的电子邮件消息 - 到子进程。
我想做的基本上是在执行此操作之前发送另一个消息副本。我不能再次使用 execv ,因为那时执行将停止。所以我尝试了以下方法:
if local in ('postmaster', 'abuse', 'mailer-daemon'):
os.spawnv(os.P_WAIT, "/usr/sbin/sendmail", ("/usr/sbin/sendmail", 'other@place.com'))
os.execv("/usr/sbin/sendmail", ("/usr/sbin/sendmail", 'first@place.com'))
sys.exit(0)
但是,虽然它将消息发送到 other@place.com,但它从不将其发送到 first@place.com
这让我感到惊讶,因为我认为使用 spawn 会启动一个子进程,然后在它返回时继续在当前进程中执行(或者如果使用 P_NOWAIT,则无需等待)。
顺便说一句,我先尝试了 os.P_NOWAIT,但我在 other@place.com 收到的消息是空的,所以至少当我使用 P_WAIT 时,消息是完整地通过的。但它仍然没有被发送到 first@place.com,这是一个问题。
如果可以避免,我宁愿不使用 os.system,因为如果可以避免,我宁愿不使用 shell 环境(安全问题,可能的性能?我承认我在这里很偏执,但是如果我可以避免 os.system 我仍然想)。
我唯一能想到的是对 os.spawnv 的调用以某种方式消耗/清空 sys.stdin 的内容,但这也没有任何意义。想法?