2013-09-04 7 views
2

좋아, 그래서 오후에 대부분 디버깅을 해봤는데 수건을 던지고있다.Errno 22 with Python shutil and .move() function

학생들이 작업을 완료 한 후 작업 폴더를 서버에 다시 넣을 수있는 시스템을 만들려고합니다. 지금까지 모든 것을 처리했습니다. 일치하는 서버 폴더를 올바르게 식별하고 서버 폴더를 Archive 폴더로 이동하여 새로운 작업을 복사하는 동안 임시로 백업합니다.

그러나 마지막 비트는 나를 지탱하고 있습니다. 인수로 전달 된 폴더를 서버로 복사 할 때까지 모든 것이 아름답게 작동합니다. 여기

코드의 문제 조각 :

print "Match Source: " + match_src 

archive_folder_name = match_src.rsplit('/', 1)[1] 

print "Archive Folder Name: " + archive_folder_name 

if not (os.path.isdir(os.path.join(os.path.dirname(match_src), "Archive"))): 
    os.mkdir(os.path.join(os.path.dirname(match_src), "Archive")) 

archive_dst = os.path.join(os.path.join(os.path.dirname(match_src), "Archive"), archive_folder_name) 

print "Archived Folder Destination: " + archive_dst 

# okay, archive folder has been made. Now we need to move the old 
# stuff to this folder. 

shutil.move(match_src, archive_dst) 

# okay, archive folder is filled. Now to move the new stuff there 
print "Updated Source: " + updated_folder_path 

print "Destination: " + os.path.dirname(match_src) 

shutil.move(updated_folder_path, os.path.dirname(match_src)) 

그리고 여기 print 문에서 출력 및 오류 코드 : 내가 잘못 가고

ServerReturn mwl36$ python serverreturn_main.py /Users/mwl36/Desktop/Week\ 1 
I'm on a Mac. 
Path: /Users/mwl36/Desktop/Week 1 
Folder: Week 1 
Match Source: /Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Week 1 
Archive Folder Name: Week 1 
Archived Folder Destination: /Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Archive/Week 1 
Updated Source: /Users/mwl36/Desktop/Week 1 
Destination: /Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST 
Traceback (most recent call last): 
    File "serverreturn_main.py", line 124, in <module> 
    main() 
    File "serverreturn_main.py", line 117, in main 
    shutil.move(updated_folder_path, os.path.dirname(match_src)) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 296, in move 
    copytree(src, real_dst, symlinks=True) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 206, in copytree 
    raise Error, errors 
shutil.Error: [('/Users/mwl36/Desktop/Week 1/testfile.txt', '/Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Week 1/testfile.txt', "[Errno 22] Invalid argument: '/Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Week 1/testfile.txt'")] 

? shutil.move (src, dst)를 호출 할 때 문제없이 처음으로 작업 한 경우 왜 여기에 바코드가 표시됩니까? 초기 호출 후 지연을 추가하려고 시도했지만 효과가 없습니다.

편집 : 실제로 낯선 것은 실제로 이동을 수행하지만 데스크톱에서는 이전 폴더를 삭제하지 않는 것입니다. 기본적으로 폴더를 DST 위치로 복사하지만 자체적으로는 정리하지 않습니다.

EDIT # 2 : os.listdir을 호출하면 디렉토리가 사라 졌음을 알 수 있으며 두 번째 이동 호출 이전에 거기에있는 유일한 것은 'Archive'입니다. 내일 직장에있을 때 copy()를 테스트하고 코드에 다시 액세스 할 것입니다.

+0

copytree에 매달려있는 것 같습니다. Copytree는 dst가 이미 존재하는 위치에있을 수 없으며 최소한 문서에 대한 이해입니다. – Benjooster

+1

여기에있는 사람들을위한 질문 : 'shutil.move'가 공백이있는 인수를 허용 할 수 있습니까?즉, 다음과 같은 경우에는 실패하지 않아야합니다 :'/ Volumes/GCPSX Mac HD/... '3 개의 인자로 보이기 때문에? – erewok

+1

@erewok 원시 문자열로 입력되는 한 공백을 허용합니다. 오류가 형식으로 만족스럽지 않게 보이지만 단순히 붙여 넣기에서 stackoverflow로 들어갈 수 있습니다. – Benjooster

답변

2

shutil.move()은 원본을 대상으로 복사 한 다음 "간단한 이동"이 가능하지 않으면 원본을 제거합니다. 소스와 대상이 같은 파일 시스템에 있지 않을 때 이런 일이 발생할 수 있습니다.

이 경우 shutil.move()은 먼저 소스를 대상에 복사 한 다음 소스에서 rmtree()을 수행합니다.

복사하는 동안 shutil은 원본 파일의 바이트를 복사 한 다음 "stat"정보 (사용 권한, 수정 시간 등)를 복사합니다. 따라서 [Errno 22] Invalid argument은 바이트 복사 또는 통계 데이터 복사 중일 것입니다. 바이트를 복사하면 EINVAL 오류가 발생할 가능성이 매우 낮기 때문에 "통계"데이터를 복사하면이 오류가 발생하는 것일 수 있습니다. 내 추측이 맞다면

import shutil 
import sys 
import traceback 

orig_copystat = shutil.copystat 
def my_copystat(src, dst): 
    try: 
     orig_copystat(src, dst) 
    except Exception as e: 
     sys.stdout.write('copystat failed: %s\n' % e) 
     traceback.print_exc() 

shutil.copystat = my_copystat 

# Your script here... 

, 당신은 당신이 실행할 때 copystat failed: ... 메시지 (들) (및 스택 추적을) 표시됩니다

당신은 당신의 주요 스크립트의 시작 부분에 이런 식으로 뭔가를 추가하여 테스트 할 수 있습니다 귀하의 스크립트,하지만 그렇지 않으면 "작동"해야합니다. 위의 함수에서 오류 메시지가 표시되면 위의 함수를 변경하여 예외를 자동으로 무시하고 스크립트를 실행할 수 있습니다. 그렇지 않은 경우 위와 같이 원숭이 패치 shutil.copyfile을 시도하고 정확히 copyfile()에 예외가 발생했는지 확인하십시오.