2010-02-16 2 views
10

Я хочу, чтобы удалить необходимые файлы. У меня есть код что-то вродеУдаление файла с помощью команды rm

dir="/some/path/" 
file = "somefile.txt" 
cmd_rm= "rm -rf "+dir + file 
os.system(cmd_rm) 

В dir и file значения извлекаются из базы данных. Как я могу убедиться, что я никогда не закончил работу rm -rf /?

Что необходимо проверить перед выполнением rm -rf?

+0

Думаю, вам нужно уточнить, что именно вы просите. Что именно ты пытаешься сделать? – benno

ответ

25

Не используйте переключатель -r, если вы просто хотите удалить один файл. Кроме того, в имени файла могут быть пробелы.

Лучше использовать функции os модуля Python вместо:

dirname = "/some/path/" 
filename = "somefile.txt" 
pathname = os.path.abspath(os.path.join(dirname, filename)) 
if pathname.startswith(dirname): 
    os.remove(pathname) 

Нормализация пути с abspath и сравнивая его с целевым каталогом избегает имен файлов, как»../../../etc/passwd " или похожие.

15

Вместо этого вы можете использовать os.remove(), так как это намного менее опасно, чем то, что вы пытаетесь.

6

Во-первых, я предлагаю вам использовать функции os.remove() и os.rmdir() для работы с такими вещами. У вас будет больше портативного кода и меньше головной боли для проверки возврата команды.

Чтобы проверить, что вы пытаетесь удалить (возможно, вам не нужно просто проверять «/»), вы можете использовать некоторые регулярные выражения для сгенерированного пути или просто добавить базовый путь ко всему пути, возвращенному из вашей базы данных (в зависимости от того, что вы делаете ...).

+0

Если вы хотите проверить путь с регулярным выражением, не забудьте сделать что-то вроде os.path.realpath и/или os.path.normpath, чтобы получить каноническую и простую в использовании строку пути (в частности, без os.path.realpath() (или эквивалентного кода, который просто невозможно выполнить с помощью регулярных выражений), вы не можете знать, что «foo/bar» на самом деле ссылается на «/») –

2

Существует модуль, называемый shutil, который обеспечивает оболочечную манипуляцию с файлами. Если вы хотите удалить каталог и все файлы и каталоги в нем, используйте shutil.rmtree.

Однако он реализован в python, поэтому, если вы удаляете огромное количество файлов, то нерестится rm, но может быть быстрее, но не будет, если в пути есть пробел.

+5

Я хочу голосовать (http://docs.python.org/library/shutil.html, для ссылки), но в то же время нереститься rm не нужно терпеть неудачу из-за пробелов и т. д. (используйте подпроцесс модуль, человек!), и скорость почти наверняка не проблема (честно говоря, Python не так уж медленный, и я уверен, что этот op обычно не связан с CPU). –

2

Используйте shutil.rmtree, как говорит Дейв Кирби. Если вы хотите удалить только использование файла:

dir = "/some/path/" 
file = "somefile.txt" 
cmd = os.path.join(dir, file) 
shutil.rmtree(cmd) 

Если вы хотите удалить использование каталога:

dir = "/some/path/" 
file = "somefile.txt" 
shutil.rmtree(dir) 

Если файлы защищены от записи убедитесь, что у вас есть права на запись, прежде чем запустить этот ,

+0

Хммм, у меня ошибка при попытке rmtree с файлом (хотя он отлично работает с dir). 'OSError: [Errno 20] Не каталог' – Pat

+0

@Pat - как вы выполняете свой скрипт, 'python script.py' или' python./Script.py'? – chrissygormley

+0

Обычно что-то вроде 'python script.py' или даже'./Script.py', но в этом случае я действительно делал это в ipython REPL. – Pat

0

Предполагая, что ваше упоминание rm -rf не просто наугад, а именно то, что вам нужно, почему бы просто не называть его? Существует lib, позволяющая увеличить интеграцию с оболочкой под названием sh.

from sh import rm 

path_to_delete = '/some/path' 
if os.path.exists(path_to_delete): 
    rm('-rf', path_to_delete) 

PS Убедитесь, что вы не являетесь пользователем root и/или попросите пользователя ввести дополнительную осторожность. И, да, курите человека, чтобы избежать рекурсивного удаления одного файла;)