Why would shutil.copy() raise a permission excepti

2019-02-11 13:15发布

shutil.copy() is raising a permissions error:

Traceback (most recent call last):
  File "copy-test.py", line 3, in <module>
    shutil.copy('src/images/ajax-loader-000000-e3e3e3.gif', 'bin/styles/blacktie/images')
  File "/usr/lib/python2.7/shutil.py", line 118, in copy
    copymode(src, dst)
  File "/usr/lib/python2.7/shutil.py", line 91, in copymode
    os.chmod(dst, mode)
OSError: [Errno 1] Operation not permitted: 'bin/styles/blacktie/images/ajax-loader-000000-e3e3e3.gif'

copy-test.py:

import shutil

shutil.copy('src/images/ajax-loader-000000-e3e3e3.gif', 'bin/styles/blacktie/images')

I am running copy-test.py from the command line:

python copy-test.py

But running cp from the command line on the same file to the same destination doesn't cause an error. Why?

3条回答
戒情不戒烟
2楼-- · 2019-02-11 13:24

The operation that is failing is chmod, not the copy itself:

  File "/usr/lib/python2.7/shutil.py", line 91, in copymode
    os.chmod(dst, mode)
OSError: [Errno 1] Operation not permitted: 'bin/styles/blacktie/images/ajax-loader-000000-e3e3e3.gif'

This indicates that the file already exists and is owned by another user.

shutil.copy is specified to copy permission bits. If you only want the file contents to be copied, use shutil.copyfile(src, dst), or shutil.copyfile(src, os.path.join(dst, os.path.basename(src))) if dst is a directory.

A function that works with dst either a file or a directory and does not copy permission bits:

def copy(src, dst):
    if os.path.isdir(dst):
        dst = os.path.join(dst, os.path.basename(src))
    shutil.copyfile(src, dst)
查看更多
Rolldiameter
3楼-- · 2019-02-11 13:25

This is kind of a guess, but the first thing that pops out at me:

'bin/styles/blacktie/images'

You have no trailing slash. While I'm not sure of the implementation of shutil.copy(), I can tell you that cp will act differently depending on what OS you're running it on. Most likely, on your system, cp is being smart and noticing that images is a directory, and copying the file into it.

However, without the trailing slash, shutil.copy() may be interpreting it as a file, not checking, and raising the exception when it's unable to create a file named images.

In short, try this:

'bin/styles/blacktie/images/'
查看更多
beautiful°
4楼-- · 2019-02-11 13:36

Arguments must be:

shutil.copy('src/images/ajax-loader-000000-e3e3e3.gif', 'bin/styles/blacktie/images.ajax-loader-000000-e3e3e3.gif')
查看更多
登录 后发表回答