2015-08-13 5 views
2

Я пишу скрипт, который будет перемещать файлы в каталог .trash в домашней папке пользователя. Я хочу, чтобы добавить возможность опорожнить каталог мусора, вызвав rm -rf /home/user/.trash/* с помощью subprocess.call питона()rm все файлы в каталоге с помощью python subprocess.call

~$ touch file1 
~$ trash file1 
['mv', 'file1', '/home/rodney/.trash/'] 
~$ ls .trash 
file1 
~$ trash --empty 
['rm', '-rf', '/home/rodney/.trash/*'] 
~$ ls .trash 
file1 

Как вы можете видеть, что команда ет не удалить содержимое корзины. Однако, если я выполняю команду непосредственно в командной строке, она работает.

~$ rm -rf /home/rodney/.trash/* 
~$ ls .trash 
~$ 

Выход из следующего кода

print(cmd) 
subprocess.call(cmd) 

Что странно об этом, если я исключить * из последнего аргумента в списке CMD то подпроцесс вызов работает, но также удаляет цельные .trash. Я не хочу удалять каталог .trash; только все под ним.

Резюмируя вопрос

Это работает

import subprocess 
subprocess.call(['rm', '-rf', '/home/rodney/.trash/']) 

Это не

import subprocess 
subprocess.call(['rm', '-rf', '/home/rodney/.trash/*']) 

Почему?

+1

Почему вы выкладывая на 'rm', чтобы сделать что-то же просто, как удаление файлов в Python? –

+0

Я думал, что было бы быстрее писать, а не создавать список файлов и перемещать все подкаталоги. – rodneyxr

+0

Возможно, но в конечном итоге это принесет вам больше пользы, чтобы изучить API, которые может предложить Python. См. [Мой ответ] (http://stackoverflow.com/a/31989328/119527). В противном случае вы можете просто написать это как скрипт Bash. –

ответ

4

Не выкладывать.

Для определения файлов, которые необходимо удалить, используется glob.glob(), а shutil.rmtree() - для удаления подкаталогов.

#!/usr/bin/env python 
import os, os.path 
import glob 
import shutil 

def remove_thing(path): 
    if os.path.isdir(path): 
     shutil.rmtree(path) 
    else: 
     os.remove(path) 

def empty_directory(path): 
    for i in glob.glob(os.path.join(path, '*')): 
     remove_thing(i) 

empty_directory('trash') 

Пример:

$ tree trash/ 
trash/ 
├── aaa 
├── bbb 
├── ccc 
├── ddd 
└── sub 
    ├── iii 
    └── jjj 

1 directory, 6 files 

$ ./go.py 

$ tree trash/ 
trash/ 

0 directories, 0 files 
+1

используйте 'os.path.join (путь, '*')' вместо 'path + '/ *''. Хотя 'os.listdir (path)' может лучше выразить намерение OP * (включает '. *' Записи), чем 'glob'. – jfs

+0

Я понятия не имел, что это так просто сделать. Я пошел вперед и внедрил ваше предложение. Я не знал, что '*' не соответствует скрытым файлам, поэтому я включил и предложение J.F.Sebastian. Для empty_directory у меня есть '[remove (os.path.join (путь, f)) для f в os.listdir (path)]', и теперь все работает отлично. – rodneyxr

+0

Пожалуйста, не используйте понимание списка «только потому, что» - здесь нормальный цикл 'for' - это Pythonic. Вы создаете 'list'' None' для каждого вызова 'remove' без всякой причины. –

0

Shell expand * в имена файлов. Вам нужно передать shell=True аргумент ключевого слова, чтобы оболочка интерпретировала *.

import subprocess 
subprocess.call('rm -rf /home/rodney/.trash/*', shell=True) 

По subprocess - Frequently Used Arguments:

Если shell истинно, то указанная команда будет выполнена через оболочки. Это может быть полезно, если вы используете Python в первую очередь для расширенного потока управления , который он предлагает для большинства системных оболочек, и по-прежнему хотят удобный доступ к другим функциям оболочки, таким как оболочки, подстановочные знаки для файлов, расширение переменных окружения и расширение ~ в домашний каталог пользователя. Обратите внимание, что сам Python предлагает реализации многих оболочечных функций (в частности, glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser() и shutil) ,

+2

Просто попробовал это, и теперь я получаю 'rm: missing operand', если я использую список. Присоединение к списку удалось исправить. Благодарю. – rodneyxr

+0

@ Rodneyxr, я изменил код соответствующим образом. Спасибо за ваш отзыв! – falsetru