Прежде всего позвольте мне сказать, что я знаю, что лучше использовать модуль подпроцесса, но я редактирую код других людей, и я стараюсь сделать как можно меньше изменений, что позволяет избежать импорта любых новых модулей. Поэтому я хотел бы придерживаться в настоящее время импортированных модулей (os, sys и paths), если это вообще возможно.Как использовать os.spawnv для отправки копии электронной почты с помощью Python?
Код в настоящее время (в файле с именем postfix-to-mailman.py, что некоторые из вас могут быть знакомы с):
if local in ('postmaster', 'abuse', 'mailer-daemon'):
os.execv("/usr/sbin/sendmail", ("/usr/sbin/sendmail", '[email protected]'))
sys.exit(0)
Это прекрасно работает (хотя я думаю sys.exit (0) никогда не может быть вызвана и, следовательно, не нужна).
Я считаю, что это заменяет текущий процесс вызовом/usr/sbin/sendmail, передавая ему аргументы/usr/sbin/sendmail (для argv [0], т.е. самого себя) и '[email protected]', затем передает среду текущего процесса - включая сообщение электронной почты в sys.stdin - дочернему процессу.
Что бы я хотел сделать, это по существу отправить еще одну копию сообщения, прежде чем делать это. Я не могу использовать execv снова, потому что тогда выполнение остановится. Таким образом, я попытался следующее:
if local in ('postmaster', 'abuse', 'mailer-daemon'):
os.spawnv(os.P_WAIT, "/usr/sbin/sendmail", ("/usr/sbin/sendmail", '[email protected]'))
os.execv("/usr/sbin/sendmail", ("/usr/sbin/sendmail", '[email protected]'))
sys.exit(0)
Однако, в то время как он посылает сообщение [email protected], он никогда не посылает его [email protected]
Это удивило меня, потому что я думал, что с помощью spawn начнет дочерний процесс, а затем продолжит выполнение в текущем процессе, когда он вернется (или не ждет, если используется P_NOWAIT).
Кстати, я сначала пробовал os.P_NOWAIT, но сообщение, которое я получил на другом@place.com, было пустым, поэтому, по крайней мере, когда я использовал P_WAIT, сообщение получилось неповрежденным. Но это все еще никогда не отправляется на [email protected], что является проблемой.
Я бы предпочел не использовать os.system, если я могу избежать этого, потому что я бы предпочел не выходить в среду оболочки, если ее можно избежать (проблемы безопасности, возможная производительность?) Я признаю, что я параноик здесь , но если я смогу избежать os.system, я бы все равно хотел).
Единственное, что я могу придумать, это то, что вызов os.spawnv каким-то образом поглощает/освобождает содержимое sys.stdin, но это тоже не имеет смысла. Идеи?
Hm, который может быть частью этого, но, к сожалению, вставка sys.stdin = sys .__ stdin__ между линиями spwnv и execv не работает, хотя http://docs.python.org/library/sys. html # sys.stdin говорит, что sys .__ stdin__ должен содержать исходное значение sys.stdin в начале программы. Blech. (но спасибо за тестирование этого и предоставление подсказки на пути к решению!) – Chirael
Я думаю, что os.popen вызывает оболочку как os.system. Есть ли способ сделать то, что вы предлагаете, не выходя из командной оболочки? Я попытался сделать это с помощью popen2, 3, 4, но пока они принимают последовательности для аргументов и обходят оболочку, они не возвращают дескриптор файла, который можно записать (по-видимому). Благодаря! – Chirael
Кстати, я чувствую, что главная проблема здесь в том, что итерация по sys.stdin - это разовый процесс; похоже, нет способа вернуться к началу sys.stdin для второго вызова: -/ – Chirael