2

好吧,所以我下午的大部分时间都在调试这个,我认输了。

我正在尝试创建一个系统,该系统将在我的学生工作人员完成工作后帮助自动将工作文件夹放回服务器上。到目前为止,我已经完成了所有工作——它正确识别了匹配的服务器文件夹,并且能够将服务器文件夹移动到存档文件夹中,以便在我将新作品复制回来时临时备份它。

然而,正是最后一点阻碍了我。一切都运行良好,直到我将作为参数传递的文件夹复制回服务器的部分。

这是有问题的代码:

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))

这是这些打印语句的输出和错误代码:

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'")]

我哪里错了?如果对 do shutil.move(src, dst) 的调用第一次没有问题,为什么会在这里呕吐?我尝试在初次通话后添加延迟,但没有效果。

编辑:更奇怪的是它实际上会执行移动,但似乎永远不会删除桌面上的旧文件夹。本质上,它将文件夹复制到 DST 位置,但不会自行清理。

编辑#2:调用 os.listdir 表明该目录已经消失,并且在第二次移动调用之前唯一的东西是“存档”。我明天上班时会测试 copy() 并再次访问代码。

4

1 回答 1

2

shutil.move()将源复制到目标,如果“简单移动”不可能,则删除源。例如,当源和目标不在同一个文件系统上时,就会发生这种情况。

在这种情况下,shutil.move()就是这样做的:首先它将源复制到目标,然后rmtree()在源上执行 a。

在复制期间,shutil将复制源文件的字节,然后复制“stat”信息(权限、修改时间等)。因此,似乎[Errno 22] Invalid argument要么来自复制字节,要么来自复制统计数据。复制字节似乎不太可能导致EINVAL错误,因此最可能的解释是复制“stat”数据导致此错误。

您可以通过在主脚本的开头添加类似这样的内容来测试它:

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()引发异常的确切位置。

于 2013-09-05T00:33:09.623 回答