2012-11-07 5 views
4

shlex와 함께 subprocess.popen을 사용하여 ssh를 사용하여 원격 bash 스크립트를 호출합니다. 이 명령은 bash 자체에서 아주 잘 작동합니다. 하지만 최대한 빨리 그것을 python 및 shlex subprocess.popen 변환하려고하면 오류가 발생합니다.Python을 사용하여 ssh를 통한 파일을 원격 bash 스크립트에 cat

원격 bash는 스크립트를

#!/bin/bash 
tmp="";  
while read -r line; 
do 
    tmp="$tmp $line\n"; 
done; 
echo $tmp; 

BASH CMD의 결과 (명령 행에서 원격 bash는 스크립트를 호출)

$> ssh x.x.x.x cat < /tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt " | /path/to/bash/script.sh;" 
Bar\n 
$> 

파이썬 코드

import shlex 
import subprocess 

fn = '/tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt' 
s = """                  
ssh x.x.x.x cat < {localfile} '| /path/to/bash/script.sh;' 
""".format(localfile=fn) 

print s 

lexer = shlex.shlex(s)              
lexer.quotes = "'"               
lexer.whitespace_split = True            
sbash = list(lexer)               
print sbash                 

# print buildCmd               
proc=subprocess.Popen(sbash,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
out,err=proc.communicate()             

print "Out: " + out               
print "Err: " + err               

PYTHON SCRIPT 결과 :

$> python rt.py 

    ssh x.x.x.x cat < /tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt '| /path/to/bash/script.sh' 
['ssh', 'x.x.x.x', 'cat', '<', '/tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt', "'| /path/to/bash/script.sh'"] 
Out: 
Err: bash: /tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt: No such file or directory 
$> 

무엇이 누락 되었습니까?

+0

왜 파이썬 스크립트가 bash 스크립트에없는 것으로 보이는 인수 목록에 여분의 ''< "가 있습니까? (또는 나는 이것을 잘못 읽고 있냐?) – mgilson

+0

나는 그것을 놓쳤다, 오타. 나는 bash 명령 행에 <를 넣음으로써 그것을 바로 잡았다. – Chris

+0

'/ tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt' 파일은 로컬 또는 원격 시스템에 있습니까? 지역 일 경우 커맨드를 다르게 실행한다고 생각합니다.'cat /tmp/bef69a1d-e580-5780-8963-6a9b950e529f.txt | ssh x.x.x.x/path/to/bash/script.sh' 원격 끝에'cat'을 실행할 필요가 없습니다. (이것이 파이썬 문제를 해결할 지 확신 할 수 없다.) – Blckknght

답변

4

문제는 명령에서 셸 리디렉션을 사용하고 있지만 하위 프로세스를 사용할 때 셸이 생성되지 않는다는 것입니다.

다음 (매우 간단) 프로그램을 고려 : 우리는 당신이 ssh을 실행하는 것처럼 (foofile.txt가있는 가정)을 실행하면 이제

import sys 
print sys.argv 

을, 우리가 얻을 :

python argcheck.py ssh cat < foofile.txt " | /path/to/bash/script.sh;" 
['argcheck.py', 'ssh', 'cat', ' | /path/to/bash/script.sh;'] 

공지 사항 < foofile.txt을 그 절대로 파이썬의 명령 행 인자로 사용하지 마십시오. 이는 bash 파서가 <과 그 뒤의 파일을 가로 채고 해당 파일의 내용을 프로그램의 표준 입력으로 리다이렉트하기 때문입니다. 즉, ssh은 stdin에서 파일을 읽는 중입니다. 파일을 stdinssh으로 전달하려면 python도 사용하십시오. 아마도, 아마도 작동 할 것이다. 나를 위해


다음 작품 : bash에서

import subprocess 
from subprocess import PIPE 

with open('foo.h') as f: 
    p = subprocess.Popen(['ssh','[email protected]','cat','| cat'],stdin=f,stdout=PIPE,stderr=PIPE) 
    out,err = p.communicate() 
    print out 
    print '#'*80 
    print err 

그리고 해당 명령을

foo.h 내 로컬 컴퓨터에있는 파일입니다
ssh [email protected] cat < foo.h '| cat' 

.

+0

의사 소통()을 나의 표준으로 사용하면서 나에게 결코 일어난 일이 없다. 지금 다른 오류가 발생합니다. Out : Err : bash : cat | /path/to/bash/script.sh : 그런 파일이나 디렉토리가 없습니다. 내 로컬 컴퓨터에서 찾고있는 것 같고 실패했습니다. – Chris

+0

@Chris -'Popen' 생성자에서 열린 파일 객체를'stdin'에 직접 전달할 수 있다고 생각합니다. 그것은 아마도 약간 더 깨끗한 방법 일 것입니다. – mgilson

+0

같은 것. Err : bash : cat | /path/to/bash/script.sh : 그런 파일이나 디렉토리가 없습니다. – Chris

0

왜 중매인을 내 보내지 않고 Paramiko을 사용 하시겠습니까?

관련 문제