2013-05-08 2 views
5

내가 가지고있는 다음과 같은 세 가지 파이썬 스크립트 :배쉬와 파이썬 파이프의 차이

parent1.py

import subprocess, os, sys 

relpath = os.path.dirname(sys.argv[0]) 
path = os.path.abspath(relpath) 
child = subprocess.Popen([os.path.join(path, 'child.lisp')], stdout = subprocess.PIPE) 
sys.stdin = child.stdout 
inp = sys.stdin.read() 
print(inp.decode()) 

parent2.py :

import sys 
inp = sys.stdin 
print(inp) 

child.py :

print("This text was created in child.py") 

만약 내가 parent1.py를 다음과 같이 호출하면 :

python3 parent1.py 

는 예상 다음과 같은 출력처럼 날을 제공합니다

This text was created with child.py 

내가 가진 parent2.py 호출하는 경우 :

python3 child.py | python3 parent2.py 

을 내가 같은 출력을 얻을. 하지만 첫 번째 예제에서는 바이트로 child.py의 출력을 얻고 두 번째에서는 문자열로 직접 가져옵니다. 왜 이런거야? 그것은 파이썬과 bash pipe 사이의 차이 일까 아니면 이것을 피하기 위해 할 수있는 일이 있습니까?

+0

[이 시도] (http://stackoverflow.com/questions/3999114/linux-pipe-into-python-ncurses-script- : 당신은 유니 코드 데이터를 제공하기 위해 child.stdout 파이프를 포장하는 io.TextIOWrapper() instance을 사용할 수 있습니다 stdin-and-termios? answertab = votes # tab-top) – scott

답변

3

파이썬이 stdinstdout을 열 때 사용할 인코딩을 감지하고 text I/O을 사용하여 유니 코드 문자열을 제공합니다.

그러나 subprocess은 시작하는 하위 프로세스의 인코딩을 감지하지 않으므로 바이트를 반환합니다.

sys.stdin = io.TextIOWrapper(child.stdout, encoding='utf8') 
+2

예. OS에 하나의 종류의 파이프가 있다는 것을 추가하고 싶습니다. 그리고 이것은 bash와 Python이 동일한 것으로 사용됩니다. 스트림의 해석은 다를 수 있으며 파이썬은 두 경우를 구별합니다. 하나는 입력을 바이트로, 다른 하나는 string/unicode로 해석합니다. – Alfe

+0

고마워요. 내가 지금 'cat/bin/bash | parent2.py 'sys.stdin.read()가 바이트를 반환하지 않기 때문에 UnicodeDecodeError가 발생합니다. 이 문제를 해결할 방법이 있습니까? – Kritzefitz

+1

@Alfe : 두 경우 모두 입력을 여전히 바이트로 해석하지만, 후자의 경우에는 'TextIOWrapper'에 스트림을 자동으로 래핑합니다. 두 경우 모두 기본 바이트 스트림에서 가져 오거나 직접 래퍼를 연결할 수 있습니다. 하지만 여전히 유용한 점입니다. – abarnert