подпроцесс завершается с ошибкой при работе под супервизором

У меня есть скрипт python supervisor(e)d, который отправляет почту. Все нормально, когда я ssh и скрипт запускается из оболочки. Вывод тот же, без ошибок, конечно, и значение равно 0

evalue = -1
try:
   f = tempfile.TemporaryFile()
   f.write(body.encode('utf-8'))
   f.seek(0)
   log.debug("'%s'" % "' '".join(call))
   for s in call:
       log.debug(type(s))
   evalue = subprocess.check_call(call, stdin=f)
except Exception as e:
    log.exception(e)
finally:
    f and f.close()
    f = None
log.debug("evalue %s" % evalue)

Я вижу вывод:

mailer_v1   : DEBUG    'mailx' '-s' 'test ñññ ' '-a' '/tmp/test_ñññ_0,00_E.pdf' '-r' 'test <[email protected]>' '[email protected]'
: DEBUG    <type 'str'>
mailer_v1   : DEBUG    <type 'str'>
mailer_v1   : DEBUG    <type 'unicode'>
mailer_v1   : DEBUG    <type 'str'>
mailer_v1   : DEBUG    <type 'unicode'>
mailer_v1   : DEBUG    <type 'str'>
mailer_v1   : DEBUG    <type 'unicode'>
mailer_v1   : DEBUG    <type 'unicode'>
mailer_v1   : ERROR    execv() arg 2 must contain only strings
Traceback (most recent call last):
 File "/data/workers/mailer_v1", line 90, in <module>
   evalue = subprocess.check_call(call, stdin=f)
 File "/usr/lib/python2.7/subprocess.py", line 506, in check_call
   retcode = call(*popenargs, **kwargs)
 File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
 File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
   errread, errwrite)
 File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
   raise child_exception
TypeError: execv() arg 2 must contain only strings
mailer_v1   : DEBUG    evalue -1

Локаль в оболочке es_ES.UTF-8 и в конфиге супервизора у меня есть

environment=LC_ALL=es_ES.UTF-8

Спасибо.


person mcosta    schedule 28.03.2014    source источник
comment
Я получил решение от albertoconnor.ca/blog /2012/Jul/21/ Это была кодировка файловой системы. Кодировка sys.getfilesystem была ANSI_X3.4-1968. С env environment=LC_ALL=es_ES.UTF-8,LANG=es_ES.UTF-8,LC_LANG=es_ES.UTF-8 теперь это UTF-8   -  person mcosta    schedule 21.08.2014


Ответы (1)


Я могу воспроизвести вашу проблему, запустив скрипт в локали C:

$ LANG=C python run-subprocess.py
# -> TypeError: execv() arg 2 must contain only strings

В этом случае все кодировки ascii:

import locale
import sys

print(sys.getfilesystemencoding()) # <-- this is used for args
print(sys.stdout.encoding)
print(locale.getpreferredencoding(False))
print(locale.getpreferredencoding(True))

Если вы принудительно используете кодировку utf-8, она работает:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import check_call

cmd = [b'-s', u'test ñññ ', b'-a', u'/tmp/test_ñññ_0,00_E.pdf', b'-r', u'test']
encoding = 'utf-8' # force utf-8 no matter what
                   # `sys.getfilesystemencoding()` or
                   # `locale.getpreferredencoding(True)` say
check_call(['echo'] + [s.encode(encoding) if isinstance(s, unicode) else s
                       for s in cmd])
person jfs    schedule 28.03.2014