crontabジョブの*がファイル名に置き換えられるのはなぜですか?

crontabジョブの*がファイル名に置き換えられるのはなぜですか?

私のクリーンドッカーログスクリプトは次のとおりです(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 ========"

crontabを使用して実行する場合:

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

出力ログは次のとおりです。

[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=

動作させるにはどうすればよいですか?

答え1

私の答えで述べたように前の質問*.log、呼び出し前にシェルが現在のディレクトリの名前にパターンを拡張しないようにパターンを引用する必要がありますfind

それ以外の場合は繰り返さないでくださいfind(例:検索結果を繰り返すのはなぜ悪い習慣ですか?")。

あなたの場合

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  

次のように書き換えることができます。

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 {} +

truncateまたはGNUユーティリティがある場合

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

またはGNUを使用してfind

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

2番目のループは同じ方法で書き換えまたは結合できます。

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 {} +

皆さんも見てください」「find」の-execオプションについて」。

スクリプトは標準sh構文のみを使用するため、最初の行を#!/bin/sh

答え2

使用される2行をfind変更する必要があります。たとえば、次のようになります。

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

質問は引用されていません*.log。一重引用符で囲みます'*.log'

その理由は、引用符がない場合は、シェルがそれにアクセスして現在のディレクトリのファイルと一致するように拡張できるためです。複数のログファイルがある場合は、次のfindエラーが発生します。

find /var/lib/docker/ -type f -name aa.log bb.log cc.log -size +25M

関連情報