Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 15, 2011 11:28:38

Brain89
От:
Зарегистрирован: 2011-04-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Перемещение содержимого папки

Здравствуйте. Хочу переместить содержимое папки в другую. Для этого использую вызов 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
то все будет нормально.



Отредактировано (Апрель 15, 2011 11:29:36)

Офлайн

#2 Апрель 15, 2011 11:47:27

Vader
От:
Зарегистрирован: 2010-01-30
Сообщения: 152
Репутация: +  0  -
Профиль   Отправить e-mail  

Перемещение содержимого папки

А что вам мешает использовать shutil?



Офлайн

#3 Апрель 15, 2011 12:20:22

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Перемещение содержимого папки

Наиболее близкий аналог mv -f /dir/_222/* /dir/222

os.system("mv -f /dir/_{0}/* /dir/{0}".format(id))
Еще одни вопрос - а какая у вас текущая директория получается при работе скрипта?
os.system("ls")



Отредактировано (Апрель 15, 2011 12:21:44)

Офлайн

#4 Апрель 15, 2011 12:57:03

Brain89
От:
Зарегистрирован: 2011-04-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Перемещение содержимого папки

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



Отредактировано (Апрель 15, 2011 13:16:49)

Офлайн

#5 Апрель 15, 2011 14:01:02

Vader
От:
Зарегистрирован: 2010-01-30
Сообщения: 152
Репутация: +  0  -
Профиль   Отправить e-mail  

Перемещение содержимого папки

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)



Офлайн

#6 Апрель 15, 2011 14:19:55

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Перемещение содержимого папки

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



Отредактировано (Апрель 15, 2011 14:20:34)

Офлайн

#7 Апрель 15, 2011 14:55:44

Brain89
От:
Зарегистрирован: 2011-04-11
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Перемещение содержимого папки

ZAN
Спасибо за подробные разъяснения. Теперь все работает и через subprocess.Popen



Отредактировано (Апрель 15, 2011 14:56:37)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version