Remova 50GB dos arquivos mais antigos em busybox quando a capacidade usada atingir 95%

3

Ok, eu pedi um código aqui, mas inicial eu não pedi para torná-lo busybox compatível. Minha culpa. Eu sou novo no Linux e codificação.

O código precisa fazer o seguinte:

Delete 50GB of oldest data (dir with files) from a directory when the HD reaches a capacity of 95%.

O código que eles me deram é que não está funcionando com o busybox:

DIRS="a/ b/"
MAXDELBYTES="53687091200" # 50GB
DELBYTES="0"

find $DIRS -type f -printf "%T@ %s %p\n" | sort -r -n | while read time bytes filename
do
    rm -fv "$filename"
    DELBYTES=$((DELBYTES + bytes))

    if [ $DELBYTES -ge $MAXDELBYTES ]; then break; fi
done

O que não está funcionando:

  • -printf (alterou para -print)
  • % T @% s% p \ n (não sabe o que mudar para)
  • Não sei o que mais não está funcionando. Eu sou novo em codificação e Linux.

Agora, isso precisa ser traduzido para busybox, para que funcione no meu sistema Linux embarcado. Além disso, um comando cron precisa ser adicionado para que seja executado toda sexta-feira.

    
por Jasper 23.08.2012 / 09:21

2 respostas

5

Como a implementação busybox do find não oferece formatação de saída personalizada, você precisa terceirizar a tarefa de formatação para um programa separado :) Felizmente, até busybox inclui o prático comando stat . Seus campos de formato de saída são diferentes daqueles que o GNU find usa, então os símbolos que você precisa usar são diferentes. O script abaixo assume que find e stat são aqueles provenientes de busybox .

DIRS="a/ b/"
MAXDELBYTES="53687091200" # 50GB
DELBYTES="0"

find $DIRS -type f -exec stat -c "%Y %s %n" {} \; | sort -r -n | while read time bytes filename
do
    rm -fv "$filename"
    DELBYTES=$((DELBYTES + bytes))

    if [ $DELBYTES -ge $MAXDELBYTES ]; then break; fi
done

Como sempre, leia a descrição de cada comando antes de usá-lo. No caso de busybox , você não encontrará manpages para eles, mas você pode usar --help para exibir informações de uso.

Esteja avisado, que esta solução pode quebrar coisas em uma situação improvável, quando os nomes dos arquivos contiverem novos símbolos neles! Isso não deve ocorrer em um sistema saudável, mas pode acontecer, por exemplo, se alguém conseguir invadir o sistema ou explorar alguma vulnerabilidade que permita a criação arbitrária de arquivos.

Para evitar a remoção acidental de arquivos úteis nesses casos, você deve primeiro localizar e remover todos os arquivos que incluam novas linhas em seus nomes. Para listar esses, execute:

find / -name "*
*"

(Existe somente uma nova linha entre os asteriscos.) Então, quando tiver certeza de que todos esses arquivos não são necessários, exclua-os usando

find / -name "*
*" -delete

ou

find / -name "*
*" -print0 | xargs -0 rm -vf

Ambos devem funcionar com busybox .

    
por 23.08.2012 / 16:28
2

Geralmente, é uma má ideia analisar a saída de ls . Mas em um sistema embarcado que não possui stat , nem zsh, nem find -printf , nem perl ou outra linguagem de script grande, é a única maneira de classificar arquivos por data. Supondo que seus nomes de arquivo não contenham espaços em branco e nenhum de \'" (que xargs manipula) - uma suposição de que seu script original faz - você pode usar xargs ls -str para exibir arquivos classificados por data e exibir seu tamanho no processo .

find $DIRS -type f |
xargs ls -str |
while read kilobytes filename; do …

Observe que o tamanho é exibido em kilobytes em vez de bytes. Além disso, esse é o espaço em disco ocupado pelo arquivo, e não o número de bytes no arquivo. Normalmente, esse número é o tamanho do arquivo, arredondado para o próximo número inteiro de blocos, mas pode ser menor se o arquivo for escasso . Em um script que libera espaço em disco, provavelmente é isso que você quer.

Há uma grande limitação com o script acima: ele só imprimirá seus resultados na ordem correta se o número de arquivos for pequeno o suficiente para que xargs possa fazer uma única chamada para ls . Se houver várias chamadas para ls , cada chamada classificará seus argumentos separadamente. Você pode imprimir as datas do arquivo com ls , mas classificar essa saída legível é muito complicado. Uma solução melhor para, pelo menos, detectar o caso de erro é substituir a saída de find na linha de comando.

{ set -f; IFS='
'; ls -str $(find $DIRS -type f); } |
while read -r kilobytes filename; do …
    
por 24.08.2012 / 01:01