Ошибка получения запрещенного разрешения при выполнении команды через subprocess.Popen, но не в оболочке - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь переместить папку в другую папку, но получаю сообщение об ошибке «Отказано в доступе», когда я пытаюсь выполнить эту операцию в скрипте Python, и перемещение успешно работает, когда я запускаю ее в bash или даже в интерактивном режиме Python.

cmd = ['sudo', 'mv', '/path1/dir', '/path2']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
     print(stderr)    

Я также пытался добавить shell = True.

p = subprocess.Popen(' '.join(cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
     print(stderr)

В обоих случаях я получаю следующую ошибку:

 "mv: cannot move '/path1/dir' to '/path2/dir': Permission denied\n"

Я вызываю свой скрипт вследующим образом:

sudo python script.py

Я пытался выполнить каждую команду в оболочке, а также в интерактивном режиме Python, и я не получаю никаких ошибок.Есть идеи, что здесь происходит?

1 Ответ

0 голосов
/ 02 октября 2018

Потратив часы на отладку времени на то, что пошло не так, я наконец понял, что происходит.Я создавал /path1 и /path2, используя tempfile.Вот фрагмент кода:

class UtilitiesTest(unittest.TestCase):
    @staticmethod
    def createTestFiles():
        dir = tempfile.mkdtemp()
        _, file = tempfile.mkstemp(dir=dir)
        return dir, file

    def test_MoveFileToAnotherLocation(self):
        src_dir, src_file = UtilitiesTest.createTestFiles()
        dest_dir, dest_file = UtilitiesTest.createTestFiles()
        cmd = ['sudo', 'mv', src_dir, dest_dir]
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = p.communicate()
        if p.returncode != 0:
             print(stderr)

Как сказал zwer в комментариях, если я запускаю этот скрипт с использованием sudo, мне не нужно добавлять sudo в мою команду mv.Поскольку я продолжал получать ошибки об отказе в разрешении, я думал, что sudo решит мою проблему.Фактическая проблема заключалась в том, что когда вызывается tempfile.mkstemp (), он возвращает дескриптор файла open вместе с путем к файлу.Я не обращал особого внимания на первый аргумент, поэтому, когда я изменил свой метод createTestFiles () ниже, все начало работать.

    @staticmethod
    def createTestFiles():
        dir = tempfile.mkdtemp()
        fd, file = tempfile.mkstemp(dir=dir)
        os.close(fd)
        return dir, file
...