Ho un certo numero di file di registro nel modulo:
log.2014-02-19-10_24_22
Cioè. log.AAAA-MM-GG-H24_MI_SS
La data che fa parte del nome del file di registro corrisponde alla prima creazione del file di registro. Quindi in qualsiasi momento posso avere i seguenti file di registro nella mia directory:
log.2014-02-19-10_18_54
log.2014-02-19-10_21_20
log.2014-02-19-10_23_11
etc.
Ora ho uno script che viene invocato da un cronjob e che elimina i "vecchi" file di registro:
$ cat delete-old-rotated-logs
#!/usr/bin/env bash
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -exec rm {} ;
Il problema che sto affrontando è che a volte il processo di registrazione si è arrestato in modo anomalo, quindi anche il file di registro "ultimo" diventa "vecchio" dopo un po' di tempo (poiché nessun processo sta scrivendo su di esso) e viene eliminato, perdendomi così la traccia. Come posso riscrivere i delete-old-rotated-logs
script in modo che elimini i vecchi file tranne l'ultimo (o l'ultimo N
) ? Per l'ordinazione si può utilizzare sia il nome del file stesso che il timestamp di modifica (più robusto).
Risposta accettata:
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 |
sort | head -n -1 | xargs rm
O se vuoi usare mtime
invece del nome del file:
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -exec ls -t {} + |
tail -n +2 | xargs rm
Dai commenti di @Stephane, un approccio più solido sarebbe da fare:
IFS=$'n'
set -f
rm $(
find /home/foo -maxdepth 1 -iname log* ! -name $'*n*' -type f -mmin +1800 |
sort | head -n -1 )
O per la shell POSIX (richiede ancora gli strumenti GNU):
IFS='
'
ex_newline='*
*'
set -f
rm $(
find /home/foo -maxdepth 1 -iname log* ! -name "$ex_newline" -type f -mmin +1800 |
sort | head -n -1 )
Una singola pipeline (robusta) può essere utilizzata con una versione recente di GNU sed
/sort
(e GNU trova come con tutto quanto sopra):
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -print0 |
sort -z | sed -z '$d' | xargs -0 rm