Найти - Пользователи
Полная версия: Перемещение содержимого папки
Начало » Python для новичков » Перемещение содержимого папки
1
Brain89
Здравствуйте. Хочу переместить содержимое папки в другую. Для этого использую вызов subprocess.Popen(“mv”…):
st_out = subprocess.Popen(["mv", "-f", r"/dir/_{0}/*".format(id), r"/dir/{0}".format(id)], bufsize=-1, close_fds=True, shell=False, universal_newlines=True, stdout=subprocess.PIPE).communicate()
Но не могу понять, в чем проблема: содержимое папки не копируется без символа “*”, но если его указать, появляется вот такая ошибка:
mv: не удалось выполнить stat для «/dir/_222/*»: Нет такого файла или каталога
Если выполнить команду в командном интерпретаторе
mv -f /dir/_222/* /dir/222
то все будет нормально.
Vader
А что вам мешает использовать shutil?
doza_and
Наиболее близкий аналог mv -f /dir/_222/* /dir/222
os.system("mv -f /dir/_{0}/* /dir/{0}".format(id))
Еще одни вопрос - а какая у вас текущая директория получается при работе скрипта?
os.system("ls")
Brain89
Vader

Если сделать, используя copy tree:
shutil.copytree(r"/dir/_{0}/*".format(id), r"/dir/{0}".format(id), symlinks=True)
Будет та же самая ошибка:
Traceback (most recent call last):
***
File "/usr/lib64/python2.7/shutil.py", line 168, in copytree
names = os.listdir(src)
OSError: [Errno 2] No such file or directory: '/dir/_222/*'
Если сделать, используя copy tree, указывая в качестве src саму директорию:
shutil.copytree(r"/dir/_{0}".format(id), r"/dir/{0}".format(id), symlinks=True)
То появится сообщение:
Traceback (most recent call last):
***
File "/usr/lib64/python2.7/shutil.py", line 174, in copytree
os.makedirs(dst)
File "/usr/lib64/python2.7/os.py", line 157, in makedirs
mkdir(name, mode)
OSError: [Errno 17] File exists: '/dir/222'
Удалить директорию '/dir/222' нет возможности, так как она является точкой монтирования активного логического тома.

Вот что имеем, используя shutil.move:
shutil.move(r"/dir/_{0}/*".format(id), r"/dir/{0}".format(id))
Traceback (most recent call last):
***
File "/usr/lib64/python2.7/shutil.py", line 292, in move
copy2(src, real_dst)
File "/usr/lib64/python2.7/shutil.py", line 127, in copy2
copyfile(src, dst)
File "/usr/lib64/python2.7/shutil.py", line 81, in copyfile
with open(src, 'rb') as fsrc:
IOError: [Errno 2] No such file or directory: '/dir/_222/*'
В этом случае ошибка та же.
При попытке просто переместить папку получаем:
shutil.move(r"/dir/_{0}".format(id), r"/dir/{0}".format(id))
Большое количество ошибок из-за нехватки места на логическом томе, потому что функция, видимо, тянет с собой содержимое symlinks. Может, я и ошибаюсь, но папка, которая весит 300 Мб, почему-то не влезает на диск в 3 Гб.

Поэтому shutil не использую.

doza_and
Согласно документации Python, модуль subprocess был призван заменить os.system:
The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function.
Документация
Поэтому его не использовал сначала. Сейчас попробовал, все получилось:
os.system("mv -f /dir/_{0}/* /dir/{0}".format(id))
os.system("pwd")
pwd выдал папку, в которой я храню свои скрипты: /usr/local/bin
Vader
Shutil правильно ругается, ему * в пути не нужен.
Если директорию, в которую производится копирование, удалять нельзя, то можно сделать так:
import os, shutil
src = r'/dir/_222/'
dst = r'/dir/222/'
for node in os.listdir(src):
if os.path.isfile(os.path.join(src,node)):
shutil.copy(os.path.join(src,node), dst)
else:
shutil.copytree(os.path.join(src,node), os.path.join(dst,node), symlinks=True)
ZAN
os.system выполняет команду через шел, а шел разворачивает символ “*” в список файлов перед тем, как передать утилите аргументы коммандрой строки.
subprocess.Popen выдает ошибку “mv: не удалось выполнить stat для «/dir/_222/*»: Нет такого файла или каталога”, т.к. он интерпретирует “/dir/_222/*” как файл - mv запускается не через шел - это даже указано явно в параметре “shell=False”. Тот же эффект будет, если заэкранировать символ “*” - “mv -f /dir/_222/\* /dir/222”.
Теперь, чтобы все заработало, нужно просто указать shell=True. Там же в документации указано, что если shell=True, то команда должна быть одной строкой, а все остальные параметры пойдут, как параметры для шела, а не параметры утилиты.
>>> stdout = subprocess.Popen("mv -f /dir/_222/* /dir/222/", shell=True)
>>> os.listdir("/dir/_222")
[]
>>> os.listdir("/dir/222")
['asdf', 'asdfasdfasdf', '32q4wdf']
Brain89
ZAN
Спасибо за подробные разъяснения. Теперь все работает и через subprocess.Popen
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB