Eu escrevi um script que exclui todos, exceto os dois últimos arquivos em uma pasta:
#!/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 será executado como um trabalho cron todos os dias.
O raciocínio é o seguinte:
Obtenha uma lista de todos os arquivos usando
ls -1
(para que eu obtenha um arquivo por linha);Remova os dois últimos da lista usando
head -n -2
;Como
ls
imprime caminhos relativos, use oxargs printf
objeto para preceder o caminho da pasta e torná-lo um caminho absoluto;Envie-os para
sudo rm -rf
usarxargs
.
Todos têm acesso a esta pasta, para que qualquer pessoa possa criar e excluir qualquer arquivo nessa pasta.
O problema é: sudo rm -rf
é assustador. xargs sudo rm -rf
é incrivelmente assustador.
Quero ter certeza de que ninguém pode danificar outras pastas / sistemas criando arquivos inteligentes a serem excluídos (acidentalmente ou de propósito). Não sei, algo inteligente como:
file with / spaces.txt
o que poderia resultar em um super assustador sudo rm -rf /
.
EDIT: Meu erro, os nomes dos arquivos não podem conter /
, portanto esse problema específico não aconteceria, mas a questão sobre se há ou não outros riscos ainda permanece.
É por isso que estou usando --quoting-style=shell-always
, isso deve evitar truques com arquivos com espaços. Mas agora estou me perguntando se alguém poderia ser mais inteligente com espaços e aspas no nome do arquivo, talvez.
Meu script é seguro?
Nota: preciso sudo
porque estou acessando a pasta remotamente (de uma unidade de rede mapeada usando mount
) e não consegui fazê-la funcionar sem o sudo.
printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?/
em nome ser criado Estou tentando conseguir isso de volta aquils
saída, este já é um comando mal escrito, mesmo com a citação.ls
também usa locale para ordem de classificação, eu acho, então não vejo qual é o objetivo dehead
remover os últimos 2 (a menos que você esteja tentando se livrar.
e do..
qual o iirc não seja permitido como argumento derm
qualquer maneira. Basta usarfind /path/to/folder -type f delete
. nãosudo
se você executar a partir do cron - cron já está no nível raizRespostas:
No Linux, qualquer caractere é um nome de arquivo válido que constitui um caractere, exceto:
\0
(ASCII NUL): conforme usado para terminação de string em C/
(barra): como usado para separação de caminhoPortanto, sua abordagem definitivamente não funcionará em muitos casos, como você pode imaginar, por exemplo, ela lida com uma nova linha (
\n
) no nome do arquivo? ( Dica: não ).Algumas notas:
ls
; use ferramentas dedicadas (existe pelo menos uma para a maioria dos casos de uso)xargs
, veja se consegue se safarfind ... -exec
; na maioria dos casos, você vai ficar bem com apenasfind
sozinhoEu acho que isso vai fazer você ir por enquanto. A steeldriver já forneceu a ideia separada de NUL no comentário (
printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
), use isso como ponto de partida.fonte
find
também, obrigado pela sugestão.ls
abordagem de análise falharia, por exemplo, você considerou uma nova linha no nome do arquivo?head -z
faz? Parece ridículo, mas eu não tenhoman
neminfo
no linux do meu contêiner CoreOS ... Não foi possível encontrar na internet também. Eu recebohead: invalid option 'z'
head
(vem com o GNUcoreutils
). Aqui está a versão on-line: manpages.ubuntu.com/manpages/xenial/man1/head.1.htmlxargs
suporta algumas citações: com aspas simples, aspas duplas ou barra invertida, o que permite aceitar argumentos arbitrários¹, mas com uma sintaxe diferente da sintaxe de aspas dos shell do tipo Bourne.A implementação do GNU
ls
encontrada no Ubuntu não possui nenhum modo de citação compatível com oxargs
formato de entrada.É
ls --quoting-style=shell-always
compatível com os shells ksh93, bash e zsh, citando a sintaxe, mas somente quando a saída dels
é interpretada pelo shell no mesmo código do idioma quels
era quando a produziu. Além disso, alguns códigos de idioma, como aqueles que usam BIG5, BIG5-HKSCS, GBK ou GB18030, devem ser evitados.Então, com essas conchas, você pode realmente fazer:
Mas isso tem pouca vantagem sobre:
O único caso em que isso se torna útil é quando você deseja usar a
-t
opção dels
classificar os arquivos por mtime / atime / ctime ou-S
/-V
. Mas, mesmo assim, você também pode usarzsh
's:por exemplo, para classificar os arquivos por mtime (use
oL
para-S
en
para-V
).Para remover todos, exceto os dois arquivos regulares modificados mais recentemente:
Still ainda existem algumas limitações de comprimento (por
execve()
algumasxargs
implementações não-GNU e arbitrárias muito mais baixas), e algumasxargs
implementações não-GNU sufocam as entradas que contêm sequências de bytes que não formam caracteres válidos.fonte