-3

My clean docker log script like this(CentOS 7):

#!/usr/bin/env bash

set -uex

echo "======== start clean docker containers logs ========"  
logs=$(find /var/lib/docker/ -type f -name *.log -size +25M)  
for log in $logs  
  do  
    echo "clean logs : $log"  
    cat /dev/null > $log  
  done  
logsrm=$(find /var/lib/docker/ -mtime +7 -name *.log -type f)  
for logm in $logsrm  
  do  
    echo "delete logs : $logm"  
    cat /dev/null > $logm
  done
echo "======== end clean docker containers logs ========"

and when I execute it using crontab:

*/1 * * * * root /data/scripts/docker-clean.sh >> $HOME/cron.log 2>&1

the output log like this:

[root@uat-k8s-01 ~]# tail -f cron.log
++ find /var/lib/docker/ -type f -name cron.log cront.log -size +25M
find: paths must precede expression: cront.log
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
+ logs=
+ echo '======== start clean docker containers logs ========'
======== start clean docker containers logs ========
++ find /var/lib/docker/ -type f -name cron.log cront.log -size +25M
find: paths must precede expression: cront.log
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
+ logs=

what should I do to make it work right?

Kusalananda
  • 333,661
Dolphin
  • 609

2 Answers2

3

As I mentioned in my answer to your previous question, the pattern *.log must be quoted to stop the shell from expanding the pattern to names in the current directory before find is invoked.

In addition to that, do not loop over the output of find (see e.g. "Why is looping over find's output bad practice?").

In your case, the loop

logs=$(find /var/lib/docker/ -type f -name *.log -size +25M)  
for log in $logs  
  do  
    echo "clean logs : $log"  
    cat /dev/null > $log  
  done  

could be rewritten as

find /var/lib/docker -type f -name '*.log' -size +25M -exec sh -c '
for log
  do
    echo "clean logs : $log"  
    cat /dev/null > "$log"
  done' sh {} +

or, if you have the GNU truncate utility,

find /var/lib/docker -type f -name '*.log' -size +25M \
    -exec echo "clean logs: " {} \; -exec truncate --size=0 {} +

or, with GNU find,

find /var/lib/docker -type f -name '*.log' -size +25M \
    -printf 'clean logs: %p\n' -exec truncate --size=0 {} +

And the second loop could be rewritten in the same way, or you could combine them:

find /var/lib/docker -type f -name '*.log' \
    \( \( -size +25M -printf 'clean logs: %p\n'  \) -o \
       \( -mtime +7  -printf 'delete logs: %p\n' \) \) -exec truncate --size=0 {} +

See also "Understanding the -exec option of `find`".

Since your script is only using standard sh syntax, you could additionally change the first line to #!/bin/sh.

Kusalananda
  • 333,661
  • You are actually lucky there were two .log files in /var/lib/docker. If there was only one (e.g. foo.log), then the find arg would have been expanded to foo.log in the shell, and find would have searched for that exact name, and you would never know it was failing to report .log files because it was looking for the wrong thing. – Paul_Pedant Apr 19 '20 at 11:57
  • @Paul_Pedant Two such files in the current directory, but yes. – Kusalananda Apr 19 '20 at 12:01
  • 1
    My bad. My house style is to cd into the base directory, and find . or find * as needed, so I get those shorter relative names. Thus my cwd and start point are synonymous. – Paul_Pedant Apr 19 '20 at 12:39
  • @Paul_Pedant cd to a known location is a good general rule. – Kusalananda Apr 19 '20 at 12:42
1

The two lines using find need to be changed, for example,

find /var/lib/docker/ -type f -name *.log -size +25M

The problem is the unquoted *.log. Put it in single quotes, '*.log'.

The reason is that when it's unquoted the shell can get to it and expand it to match files in the current directory. If you have two or more log files present you'll get something like this, which will trigger the find error you're seeing

find /var/lib/docker/ -type f -name aa.log bb.log cc.log -size +25M
Chris Davies
  • 116,213
  • 16
  • 160
  • 287