Escribí un script que elimina todos excepto los dos últimos archivos en una carpeta:
#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder \
| head -n -2 \
| xargs printf -- "'/path/to/some/folder/%s'\n" \
| xargs sudo rm -rf
Este script se ejecutará como un trabajo cron todos los días.
El razonamiento es como sigue:
Obtenga una lista de todos los archivos usando
ls -1(para que obtenga un archivo por línea);Elimine los dos últimos de la lista usando
head -n -2;Dado que
lsimprime rutas relativas, use el elementoxargs printfpara anteponer la ruta de la carpeta y convertirla en una ruta absoluta;Envíalos a
sudo rm -rfusarxargs.
Todos tienen acceso a esta carpeta, por lo que cualquiera puede crear y eliminar cualquier archivo en esta carpeta.
El problema es: sudo rm -rf da miedo. xargs sudo rm -rfEs increíblemente aterrador.
Quiero asegurarme de que nadie pueda dañar otras carpetas / sistemas creando archivos inteligentes que se eliminen (ya sea accidentalmente o a propósito). No sé, algo inteligente como:
file with / spaces.txt
lo que podría resultar en un súper miedo sudo rm -rf /.
EDITAR: Mi error, los nombres de archivo no pueden contener /, por lo que este problema específico no sucedería, pero la pregunta sobre si existen otros riesgos o no.
Es por eso que estoy usando --quoting-style=shell-always, esto debería evitar cualquier truco con archivos con espacios. Pero ahora me pregunto si alguien podría ser más inteligente con espacios y comillas en el nombre de archivo, tal vez.
¿Es seguro mi script?
Nota: Lo necesito sudoporque estoy accediendo a la carpeta de forma remota (desde una unidad de red asignada usando mount), y no pude hacer que funcione sin sudo.

printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm?/Puedo crear un archivo con el personaje en el nombre? Estoy tratando de lograr esto aquílssalida, este ya es un comando mal escrito, incluso con comillas.lscreo que también usa la configuración regional para ordenar el orden, así que no veo cuál es el propósito deheadeliminar los últimos 2 (a menos que estés tratando de deshacerte.y de..qué iirc no están permitidos como argumentos dermtodos modos. Solo usafind /path/to/folder -type f delete. Y nosudosi se ejecuta desde cron - cron ya está en el nivel raízRespuestas:
En Linux, cualquier carácter es un nombre de archivo válido que constituye un carácter, excepto:
\0(ASCII NUL): como se usa para la terminación de cadena en C/(barra inclinada): como se usa para la separación del caminoEntonces, su enfoque definitivamente no funcionará en muchos casos, como puede imaginar, por ejemplo, ¿maneja una nueva línea (
\n) en el nombre del archivo? ( Sugerencia: no ).Pocas notas:
ls; use herramientas dedicadas (hay al menos una para la mayoría de los casos de uso)xargs, vea si puede salirse con la suyafind ... -exec; en la mayoría de los casos, estarás bienfindsoloCreo que esto te pondrá en marcha por ahora. steeldriver ya proporcionó la idea separada por NUL en el comentario (
printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm), use esto como punto de partida.fuente
findtambién, gracias por la sugerencia.lsenfoque de análisis podría fallar, por ejemplo, ¿tuvo en cuenta una nueva línea en el nombre del archivo?head -z? Suena ridículo, pero no tengomanniinfoen mi contenedor CoreOS Linux ... Tampoco pude encontrar en Internet. Obtengohead: invalid option 'z'head(viene con GNUcoreutils). Aquí está la versión en línea: manpages.ubuntu.com/manpages/xenial/man1/head.1.htmlxargsadmite algunas citas: con comillas simples, comillas dobles o barra diagonal inversa que le permite aceptar argumentos arbitrarios¹, pero con una sintaxis que es diferente de la sintaxis de comillas tipo Bourne.La implementación de GNU
lscomo se encuentra en Ubuntu no tiene ningún modo de cotización que sea compatible con elxargsformato de entrada.Su
ls --quoting-style=shell-alwayses compatible con ksh93, golpe y conchas zsh citando sintaxis, pero sólo cuando la salida dellses interpretado por el shell en el mismo lugar comolsera cuando salida de él. Además, se deben evitar algunos entornos locales, como los que usan BIG5, BIG5-HKSCS, GBK o GB18030.Entonces, con esos proyectiles, puedes hacer:
Pero eso tiene poca ventaja sobre:
El único caso en el que se vuelve útil es cuando desea utilizar la
-topción delsordenar los archivos por mtime / atime / ctime o-S/-V. Pero incluso entonces, también podrías usarzsh:por ejemplo, para ordenar los archivos por mtime (use
oLfor-Synfor-V).Para eliminar todos menos los dos archivos regulares modificados más recientemente:
¹ todavía hay algunas limitaciones de longitud (por
execve()y en algunasxargsimplementaciones no GNU arbitrarias mucho más bajas), y algunasxargsimplementaciones no GNU ahogarán la entrada que contiene secuencias de bytes que no forman caracteres válidos.fuente