2017-12-06 11 views
-1

내가 작동이 Python2.7 스크립트가를 포함해야하는 경우 LANG = 'C'! 리눅스 쉘에형식 오류 : execv와() 인수 2 만 문자열 (하위 프로세스 및 유니 코드)

# -*- coding: utf-8 -*- 
from __future__ import absolute_import, division, unicode_literals, print_function 

import os 
import subprocess 

import sys 

print('LANG: {}'.format(os.environ['LANG'])) 
print('sys.getdefaultencoding(): {}'.format(sys.getdefaultencoding())) 
print('sys.getfilesystemencoding(): {}'.format(sys.getfilesystemencoding())) 
subprocess.check_call(['echo', 'Umlauts üöä']) 

전화 :

[email protected]:~$ python src/execv-arg-2-must-contain-only-strings.py 
LANG: de_DE.UTF-8 
sys.getdefaultencoding(): ascii 
sys.getfilesystemencoding(): UTF-8 
Umlauts üöä 

하지만이 실패

[email protected]:~$ LANG=C python src/execv-arg-2-must-contain-only-strings.py 
LANG: C 
sys.getdefaultencoding(): ascii 
sys.getfilesystemencoding(): ANSI_X3.4-1968 
Traceback (most recent call last): 
    File "src/execv-arg-2-must-contain-only-strings.py", line 12, in <module> 
    subprocess.check_call(['echo', 'Umlauts üöä']) 
    File "/usr/lib/python2.7/subprocess.py", line 536, in check_call 
    retcode = call(*popenargs, **kwargs) 
    File "/usr/lib/python2.7/subprocess.py", line 523, in call 
    return Popen(*popenargs, **kwargs).wait() 
    File "/usr/lib/python2.7/subprocess.py", line 711, in __init__ 
    errread, errwrite) 
    File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child 
    raise child_exception 
TypeError: execv() arg 2 must contain only strings 

내가 LANG = C로 Python2.7에서이 스크립트를 작동하게하기 위해 무엇을 할 수 있는가?

+0

이 UTF-8 (_unicode_)에 호출 인수를 디코딩 시도 :-), 다음을 인코딩 즉,'subprocess.check_call ([ 'echo', 'Umlauts üöä'.decode ("utf-8"). encode (sys.getdefaultencoding()))'기본 인코딩으로 변경합니다. 서브 프로세스/쉘이 유니 코드 환경에서 실행되지 않는 한 일반적으로 유니 코드 데이터를 인수로 전달하는 것은 좋지 않습니다. 이러한 데이터를 STDOUT 파이프를 통해 전달하는 것이 훨씬 안전합니다. – zwer

+0

@zwer 나는 STDIN 파이프를 의미하는 것 같아. 그럼에도 불구하고, 귀하의 의견에 감사드립니다. 왜 대답으로 쓰지 않을까요? – guettli

+0

기술적 인면에서 파이프는 호출자의 STDOUT과 calee의 STDIN 사이에 서있을 것입니다. – zwer

답변

1

사용 LANG = C.UTF-8 대신 LANG = C

[email protected]> LANG=C.UTF-8 python t.py 
LANG: C.UTF-8 
sys.getdefaultencoding(): ascii 
sys.getfilesystemencoding(): UTF-8 
Umlauts üöä 

0

정확함을 확인할 방법이 없으므로 답변으로 게시하지 않았습니다. 그러나 원칙적으로 데이터를 서브 프로세스/쉘 인수로 보내려면 해당 데이터의 인코딩과 일치해야합니다 (그리고 수신 서브 프로세스에서 다시 디코딩). 그렇지 않으면 파이썬은 인수를 압축하는 방법을 알 수 없습니다.

그래서, 당신은 함께 작업하는 경우 utf-8 문자 (인코딩 헤더에 정의 된대로) 및 서브 프로세스로 보내려면, 먼저 다음, 기본 유니 코드 객체에 디코딩에 인코딩해야 무엇이든 예를 들어, 현재 환경의 시스템의 인코딩입니다 :

literal_argument = "Umlauts üöä" # string literal 
unicode_argument = literal_argument.decode("utf-8") # unicode 
encoded_argument = unicode_argument.encode(sys.getdefaultencoding()) # sys encoded 

subprocess.check_call(['echo', encoded_argument]) 

안전하지만, 아직 표준이 아닌 쉘에서 휴식 할 수 있습니다. 가능한 경우 하위 프로세스의 STDIN 파이프를 사용하여 현재 쉘에 적합하지 않은 데이터를 인수로 전달하십시오. 그러면 양쪽 프로세스가 사용할 인코딩에 동의하는 한 다른 코드 페이지에 대해 걱정할 필요가 없습니다.