2010-02-16 12 views
10

Quiero asegurarme de eliminar los archivos necesarios. tengo código de algo así comoEliminación de archivos utilizando el comando rm

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

Los dir y file valores se obtienen de una base de datos. ¿Cómo puedo asegurarme de que nunca termine ejecutando rm -rf /?

¿Qué cosas debo comprobar antes de hacer rm -rf?

+0

Creo que necesita aclarar exactamente lo que está preguntando. ¿Qué estás tratando de hacer exactamente? – benno

Respuesta

25

No utilice el interruptor -r si solo desea eliminar un solo archivo. Además, podría haber espacios en el nombre del archivo.

un mejor uso de las funciones en el módulo de Python os lugar:

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

La normalización de la ruta con abspath y comparándolo con el directorio de destino evita nombres de archivo como" ../../../etc/passwd " o similar.

15

En su lugar, podría considerar usar os.remove() ya que es mucho menos peligroso que lo que está intentando.

6

Primero, sugiero que use las funciones os.remove() y os.rmdir() para trabajar con cosas como esas. Obtendrá más código portátil y menos dolor de cabeza para comprobar el retorno del comando.

Para comprobar lo que está intentando eliminar (puede que no desee simplemente marcar "/"), puede usar algunas expresiones regulares en la ruta generada o simplemente agregar una ruta base a todas las rutas devueltas desde su base de datos (dependiendo de lo que estés haciendo ...).

+0

Si desea consultar la ruta con una expresión regular, no olvide hacer algo como os.path.realpath y/o ospath.normpath para obtener una cadena de ruta de acceso canónica y fácil de tratar (en particular, sin os.path.realpath() (o código equivalente que simplemente no se puede hacer con expresiones regulares), no tienes forma de saber que "foo/bar" se refiere a "/") –

2

Hay un módulo llamado shutil que proporciona manipulación de archivos tipo shell. Si desea eliminar un directorio y todos los archivos y directorios, utilice shutil.rmtree.

Sin embargo, está implementado en python por lo que si está eliminando una gran cantidad de archivos, la rm de desove puede ser más rápida, pero fallará si la ruta tiene un espacio en ella.

+5

Quiero votar usted está listo para la sugerencia de shutil (http://docs.python.org/library/shutil.html, para un enlace), pero al mismo tiempo, no es necesario que falle el engendramiento debido a espacios, etc. (use el subproceso ¡Módulo, hombre!), y la velocidad casi no es un problema (francamente, Python no es tan lento, y estoy bastante seguro de que esta operación no suele estar vinculada a la CPU). –

2

Use shutil.rmtree como Dave Kirby dice. Si desea eliminar el simple uso de archivos:

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

Si desea eliminar el uso de directorios:

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

Si los archivos están protegidos contra escritura asegurarse de que tiene permisos de escritura antes de ejecutar este .

+0

Hmmm, recibí un error al intentar rmtree con un archivo (aunque funciona bien con un directorio). 'OSError: [Errno 20] No es un directorio' – Pat

+0

@Pat - ¿Cómo estás ejecutando tu script,' python script.py' o 'python./Script.py'? – chrissygormley

+0

Típicamente algo así como 'python script.py' o incluso'./Script.py', pero en este caso lo estaba haciendo en el ipython REPL. – Pat

0

Asumiendo que su mención rm -rf no es solo al azar, sino que es exactamente el comando que necesita, ¿por qué no simplemente llamarlo? Hay una lib que permite una mayor integración con shell llamada sh.

from sh import rm 

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

PS Asegúrese de que no es root y/o solicite que la entrada del usuario sea extremadamente cuidadosa. Y, sí, fume al hombre para evitar borrar un solo archivo recursivamente;)

Cuestiones relacionadas