2012-11-22 3 views
1

간략화를 위해 쉘 스크립트는 cat 명령이라고 가정하십시오. 쉘에서 그것은 일반적으로 다음과 같이 호출됩니다 :파일을 디스크에 쓰지 않고 파이썬에서 쉘 스크립트 호출하기

$ cat /some/path/myfile.txt 

이제 파일을 동적으로 생성되고 디스크에 기록하는 것은 중요한 성능 저하, 현재 보안 문제를하고 다중 사용자 환경에서 파일 관리 오버 헤드가 증가 할 것 . 스크립트는 수정하거나 표준 입력에서 읽을 수 없습니다 (cat은 작동중인 샘플 일뿐입니다). 아직 명령이 여전히 파이프에서 더 많은 입력을 기다리고 있음을 보여주는 아무 것도 반환하지 않습니다 내가 poutp.poll()를 닫더라도

import os 
pin, pout = os.pipe() 
pin, pout = os.fdopen(pin, 'r'), os.fdopen(pout,'w') 

from subprocess import Popen 
pout.write("test") 
pout.flush() 
p = Popen('cat /proc/self/fd/%s' % pout.fileno(), shell=True) 

:

나는이 시도.

파이프에서 오는 데이터가 더 이상 없다는 것을 어떻게 알 수 있습니까? 이 문제를 해결하기위한 다른 방법이 있습니까?

파일 내용이 prog1라는 프로그램에 의해 생성되는 경우 편집

bash는,이이 방식으로 해결 될 것입니다 :

$ cat <(prog1) 

편집 2

당신이 만약 shell을 필요로하지 않는다면 Alfe가 언급 한 다른 옵션이 더 나을 것이다. 문제는 여전히 존재한다. (즉, 프로세스가 th 조금 주위 바이올린 전자 파일의 내용)

#...same as before 
p = Popen(['cat', '/dev/stdin'], stdin=pout) 
+0

나는 당신이 원하는 것을 이해하지 못합니다. 좋은 해결책을 찾지 못하면 [tempfile] (http : //docs.python.org/3/library/tempfile.html). –

+0

@BlaXpirit 임시 파일이 디스크에 쓰고 있지만, 유일한 조건은 그렇게하지 않는 것입니다. 질문을 수정하고 더 설명하려고합니다 – estani

답변

1

이것은 내가 마지막에했으나 좋지 않습니다.

저는 CentOS에서 작업 중이므로 문제가 있습니다 (여기에 대해 질문했습니다 : Python Popen can't open bash shell in CentOS/Red Hat) execute='/bin/bash' 이유는 해결책이 질문과 조금 다릅니다. 내가 bash는 프로세스 대체 여기-문서를 사용하여 프로세스에 일부 구성을 전달하고있어 무엇

: 지금 그것을 명명 된 파이프를 만드는의 tmpfs를 사용하여 고려 중이 야

file_contents = '...' 
p = Popen(['/bin/bash', '-c', "cat <(cat<<'EOF_CFG'\n%s\nEOF_CFG\n)" % file_contents]) 

. 그 스크립트를 먼저 시작한 다음 파이프에 쓰는 것이 효과가 있다고 생각합니다. 성공한다면 나는 여기에 글을 쓸 것입니다.

0

, 일측의 파이프를 개폐하는 자식 프로세스의 관련 의사 파일은/proc/셀프/FD/< #>에 EOF가 발생하지 않는 것으로 보인다 . 당신은/dev/stdin을 사용하여 그것을 시도해 보았고 여러분의 입력을 서브 프로세스의 표준 입력으로 간단하게 전달 했습니까?

+0

무슨 뜻인지 모르겠군요. 실행중인 스크립트는 파일을 기대하고 stdin에서 읽을 수 없습니다. (그래서'cat'은 간단한 예제 일 뿐이며 실제 스크립트는 그렇게 할 수 없습니다.) – estani

+0

/dev/stdin은 다음과 같은 가짜 파일입니다. 현재 프로세스의 표준. 시도해보십시오 :'ls | 고양이 file_a/dev/stdin file_b'. – Alfe

+0

나는 그 사실을 몰랐다! 더 나은 옵션이지만, 똑같은 문제가 있습니다. EOF가 전송되지 않습니다 ... 좋은 점은 쉘이 필요 없다는 것입니다. 필자의 경우 필자는 파일을 소스 화하고 환경을 설정해야합니다. – estani

0

이 작업을 위해 명명 된 파이프를 사용해보십시오. 그것에서 EOF 모드가 제대로 전파됩니다 : 당신은뿐만 아니라 파이썬에서 즉석에서 명명 된 파이프를 물론, 단지 os.mkfifo()을 사용하여 만들 수 있습니다

$ mkfifo bla 
$ python 
from subprocess import Popen 
p = Popen('cat bla', shell=True) 
with file('bla', 'w') as f: 
    f.write('test') 

.

+1

실제로 그것은 나의 최근 고려 사항이었습니다. Popen이 클래스 계층 구조에서 발생하고 스크립트가 끝날 때까지 차단 될 것으로 예상되는 통신을 트리거하기 때문에 특정 경우에 작동하는지 확인해야합니다. 하위 클래스는 파일처럼 작동하는 "무언가"를 전달해야합니다. 나는 그것을 시험해보아야한다. 그러나 나는 이것을 위해 두 가지 과정이 필요하다고 생각한다. – estani

관련 문제