2013-01-11 3 views
12

한 서버에서 다른 서버로 이미지를 복사하기 위해 python 스크립트의 하위 프로세스에서 ssh를 통해 rsync를 실행하려고합니다.python subprocess.call에서 rsync 호출

rsync -avz --include='*/' --include='*.jpg' --exclude='*' -e ssh /shared/books/{book_482,book_347} [email protected]:/home/jill/web/public/static/ 

그리고 실제로 내 인쇄 문 출력 :

def rsyncBookContent(bookIds, serverEnv): 
    bookPaths = "" 
    if len(bookIds) > 1: 
     bookPaths = "{" + ",".join(("book_"+str(x)) for x in bookIds) + "}" 
    else: 
     bookPaths = "book_" + str(bookIds[0]) 

    for host in serverEnv['content.hosts']: 
     args = ["rsync", "-avz", "--include='*/'", "--include='*.jpg'", "--exclude='*'", "-e", "ssh", options.bookDestDir + "/" + bookPaths, "[email protected]" + host + ":/home/jill/web/public/static/"] 
     print "executing " + ' '.join(args) 
     subprocess.call(args) 

내가 궁극적으로 할 노력하고있어 것은 파이썬 (bash 쉘에서 작동하는)이 실행이 있습니다 : 나는이 함수를 정의했습니다 :

executing rsync -avz --include='*/' --include='*.jpg' --exclude='*' -e ssh /shared/books/{book_482,book_347} [email protected]:/home/jill/web/public/static/ 

하지만이 파이썬 스크립트 내에서 실행될 때,이 두 가지 문제 :

  1. len (bookIds)> 1 인 경우/shared/books/아래의 하위 디렉토리 목록이 bash 또는 rsync에 의해 잘못 해석됩니다. 오류 메시지가 없습니다 :
    • rsync에서는 실패 link_stat "/ 공유/책/{book_482, book_347}": 그런 파일이나 디렉토리 (2))
  2. 렌 (bookIds) == 1의 경우, 소스 디렉토리 아래에있는 모든 파일은

가 subprocess.call 기능이 일부 문자가 아니, 뭔가를 탈출하거나 할 필요 것처럼 보인다 (내 의도대로, 단지 * .JPG)을 rsynced입니까?

+0

:

뉴 (일) 코드는 다음과 같습니다? 예를 들어,'subprocess.call (args, shell = True)' – sberry

답변

17

내 문제를 파악했습니다. 내 문제는 subprocess.call 함수가 어떻게 실행되는지에 대한 오해와 중괄호 안에있는 bash의 목록 확장에 따른 결과였다.

중괄호로 묶인 서브 디렉토리가있는 bash 쉘에서 rsync 명령을 실행할 때 bash는이를 실제로 rsync (/ shared/books/book_1 shared/books/book_2 등)에 전달되는 여러 인수로 확장했습니다.). "/ shared/books/{book_1, book_2}"와 같은 문자열을 중괄호로 subprocess.call 함수에 전달할 때 bash를 사용하지 않았기 때문에 확장이 발생하지 않았기 때문에 rsync에 대한 내 인수는 실제로 "/ shared/books/{book_1, book_2}".

마찬가지로 파일 패턴 ('*', '* .jpg'등) 주위의 작은 따옴표는 bash 명령 줄에서 작동합니다 (작은 따옴표 안의 값만 rsync에 전달됩니다). 그러나 하위 프로세스 .call, 작은 따옴표는 rsync에 파일 패턴 (" '* .jpg'")으로 전달됩니다. 당신이 당신의 전화에`쉘 = TRUE '를 설정하면 무슨 일이 호기심에서

def rsyncBookContent(bookIds, serverEnv): 
    bookPaths = [] 
    for b in bookIds: 
     bookPaths.append(options.bookDestDir + "/book_" + str(b)) 
    args = [] 
    for host in serverEnv['content.hosts']: 
     # copy all *.jpg files via ssh 
     args = ["rsync", "-avz", "--include", "*/", "--include", "*.jpg", "--exclude", "*", "-e", "ssh"] 
     args.extend(bookPaths) 
     args.append("[email protected]" + host + ":/home/jill/web/public/static/"]) 
     print "executing " + ' '.join(args) 
     subprocess.call(args)