Mám několik souborů protokolu ve tvaru:
log.2014-02-19-10_24_22
Tj. log.RRRR-MM-DD-H24_MI_SS
Datum, které je součástí názvu souboru protokolu, je datum, kdy byl soubor protokolu poprvé vytvořen. Takže v každém daném okamžiku mohu mít ve svém adresáři následující soubory protokolu:
log.2014-02-19-10_18_54
log.2014-02-19-10_21_20
log.2014-02-19-10_23_11
etc.
Nyní mám skript, který je vyvolán cronjobem a který odstraní „staré“ soubory protokolu:
$ cat delete-old-rotated-logs
#!/usr/bin/env bash
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -exec rm {} ;
Problém, kterému čelím, je, že někdy proces, který protokoluje, selhal, takže „nejnovější“ soubor protokolu se po nějaké době také stane „starým“ (protože do něj žádný proces nezapisuje) a je smazán, čímž ztrácím stopu. Jak mohu přepsat delete-old-rotated-logs
skript tak, že odstraní staré soubory kromě posledního (nebo posledního N
) ? Pro objednání lze použít jak samotný název souboru, tak časové razítko modifikace (robustnější).
Přijatá odpověď:
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 |
sort | head -n -1 | xargs rm
Nebo pokud chcete použít mtime
místo názvu souboru:
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -exec ls -t {} + |
tail -n +2 | xargs rm
Z komentářů @Stephane by byl robustnější přístup:
IFS=$'n'
set -f
rm $(
find /home/foo -maxdepth 1 -iname log* ! -name $'*n*' -type f -mmin +1800 |
sort | head -n -1 )
Nebo pro POSIX shell (stále vyžaduje nástroje 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 )
Jediný (robustní) kanál lze použít s poslední verzí GNU sed
/sort
(a GNU find jako u všech výše uvedených):
find /home/foo -maxdepth 1 -iname log* -type f -mmin +1800 -print0 |
sort -z | sed -z '$d' | xargs -0 rm