特定のファイルが存在することを確認しようとしています(24時間未満の場合のみ)。もしそうなら、名前が ".control"で終わるファイルが存在するかどうか、2番目の解決を行います。両方の条件が満たされると、電子メールとログエントリが生成されます。最初のファイルは存在しますが、.controlは存在しない場合は別のログエントリが生成されます。 24時間以内にファイルが存在しない場合、スクリプトの残りの部分は引き続き実行されます。
これは、Solaris および Linux で Bash を使用して cron で実行されるシェルスクリプトにあります。
if [ find "$MAINTENANCE_LOCK/testLOCK" -mtime -1 ]; then
if [ -f "$PATH_TO_TRIGGER_FILES/*.control" ]; then
test_log_msg "test_SYSTEM" $NOTICE "Valid Maintenance Lock file found, test actions blocked." "status"
test_log_email " " " " " " "test Actions were blocked because an testLOCK file less than 24hrs old is in place." " "
else
test_log_msg "test_SYSTEM" $NOTICE "Valid Maintenance Lock file in place." "status"
exit
fi
fi
ただし、「set -x Trap read debug」を使用してコード行を段階的に実行すると、次のエラーが発生します。
+ '[' find /var/opt/test/maintenancelock/testLOCK -mtime -1 ']'
/opt/test/test_control.sh: line 72: [: too many arguments
ここで私が望むことをする方法はありますか?
答え1
試してみてくださいhelp [
- help test
yes[
の同義語ヘルプには、次のように記載されていますtest
。test
テストの動作はパラメータの数によって異なります。
これにより、[ find "$MAINTENANCE_LOCK/testLOCK" -mtime -1 ];
4つの単語をに渡し[
、4つの引数で何をすべきかわかりません。
特定のファイルが存在することを確認しようとしています(24時間未満の場合のみ)。もしそうなら、名前が ".control"で終わるファイルが存在するかどうか、2番目の解決を行います。
バッシュ使用:
mapfile -t testlock < <(find "$MAINTENANCE_LOCK/testLOCK" -mtime -1)
if [[ ${#testlock[@]} -eq 0 ]]; then
echo "lock file does no exist or is too old"
else
control=( "$PATH_TO_TRIGGER_FILES/"*.control )
if [[ ${#control[@]} -gt 0 ]]; then
echo "lock file exists and at least one control file exists"
else
echo "lock file exists but no control files exist"
fi
fi
答え2
デフォルトでは、一致find
するファイルがあるかどうかにかかわらず、常にtrue(0)が返されます。
ただし、-exec
一致するファイルに対して機能する述語を使用すると、1つ/bin/false
以上の一致が見つかった場合はfalse(1)を返すことができます。否定(!
)が見つかった場合はtrue、そうでない場合はfalseをテストします。
たとえば、
# does the lock file exist?
if ! find "$MAINTENANCE_LOCK/testLOCK" -mtime -1 -exec false {} + ; then
# are there any .control files?
if ! find "$PATH_TO_TRIGGER_FILES" -name '*.control' -exec false {} + ; then
test_log_msg "test_SYSTEM" $NOTICE "Valid Maintenance Lock file found, test actions blocked." "status"
test_log_email " " " " " " "test Actions were blocked because an testLOCK file less than 24hrs old is in place." " "
else
test_log_msg "test_SYSTEM" $NOTICE "Valid Maintenance Lock file in place." "status"
exit
fi
fi
これを頻繁に実行したり、スクリプトを読みやすく、独自に文書化したい場合は、関数でラップできます。
file_exists () {
# The args to this function are passed directly to find,
# so anything that works with find will work here.
# And anything that breaks find will break this function too.
# Also, you probably don't want to use any find arguments that
# produce any output.
if ! find "$@" -exec false {} + ; then
# one or more matching files were found, return true
return 0
else
# nothing found, return false
return 1
fi
}
if file_exists "$MAINTENANCE_LOCK/testLOCK" -mtime -1 ; then
if file_exists "$PATH_TO_TRIGGER_FILES" -name '*.control' ; then
...
else
...
fi
fi
引数を完全に無視すると、/bin/false
引数の数に関係なく false(1) の終了コードのみが返されます。したがって、存在をテストする必要がある場合に便利です。いいえ必要に応じて便利です計算一致するファイルの数。これを行う必要がある場合は、次のことができます(GNU findまたは他のサポートされているfindを使用-printf
)。
if [ "$(find . -mtime -1 -printf 1 | wc -c)" -gt 10 ] ; then
: do something here
fi
これは見つかったファイルごとに文字を印刷します(どの文字が印刷されるかは重要ではありません。ここでは「1」を使用していますが、「.」、「x」、またはその他の文字に対して同じように機能します)。それらを計算するために使用されますwc -c
。 10以上の場合、if
テストはtrueと評価されます。
find
-printf
オプションをサポートしていない(POSIXではありませんがまだ一般的な)GNUではない場合は、次のものを使用-print0
できます。
if [ "$(find . -mtime -1 -print0 | awk -v RS='\0' 'END{print NR}')" -gt 10 ] ; then
: do something here
fi
このバージョンは、出力awk
にNULで区切られたレコード数(つまり、一致するファイル数)を印刷します。find
絶対に確信したらまったくファイルまたはディレクトリ名のいずれかに改行()文字が含まれている場合は、代わりに\n
POSIX標準を使用できます(そして入力をパイプすることができます)。しかし、これについて絶対に確信できないので、これは決して信頼できるものではありません。ファイル名は将来のどの時点でも存在しません。つまり、今はうまくいくかもしれませんが、明日や来年に失敗する可能性があります。-print
-print0
wc -l
答え3
コマンドはfind
複数のファイルを返す必要があるため、警告が表示されます。
ファイルを確認したい場合は、お勧めしますstat
file_btime=$(stat -c%W /var/opt/test/maintenancelock/testLOCK)
time_now=$(date %s)
file_age=$(( time_now - file_btime ))
if [ $file_age -le 86400 ] ; then
echo File is less then 24h old
fi