cronを使用して定期的に実行されるスクリプトがあります。このスクリプトが失敗した場合は、電子メール通知を受け取りたいと思います。実行され、出力が生成されるたびに通知を受けたくありません。
だからスクリプトを使用しています。クロニクcronでジョブを実行すると、エラー出力のみを送信するのではなく、エラー出力のみを送信することを意味します。どの出力。
ただし、スクリプトには次のコマンドがあります。
if [ "$(ls -A ${local_backup_location}/nextcloud-data/)" ]; then
# save space by removing diffs older than 6 months
rdiff-backup --remove-older-than 6M --force ${local_backup_location}/nextcloud-data/ || echo "[$(date "+%Y-%m-%d %T")] No existing nextcloud data backup"
fi
ls -A ${local_backup_location}/nextcloud-data/
ディレクトリが空であることをテストするように設計されています。私の問題は、このコマンドがエラー出力クロニックとして認識される出力を生成するようです。 Cronic は、エラーを追跡しないエラー出力またはゼロ以外の結果コードとして定義します。たとえば、
Cronic detected failure or error output for the command:
/usr/local/sbin/run_backup
RESULT CODE: 0
ERROR OUTPUT:
appdata_ocgcv9nemegb
files_external
flow.log
flow.log.1
__groupfolders
.htaccess
index.html
nextcloudadmin
nextcloud-db.bak
nextcloud.log
nextcloud.log.1
.ocdata
rdiff-backup-data
Test_User
updater.log
updater-ocgcv9nemegb ]
custom
gitea-db.sql
log ]
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 365 0 0 100 365 0 302 0:00:01 0:00:01 --:--:-- 303
100 365 0 0 100 365 0 165 0:00:02 0:00:02 --:--:-- 165
100 365 0 0 100 365 0 113 0:00:03 0:00:03 --:--:-- 113
100 365 0 0 100 365 0 86 0:00:04 0:00:04 --:--:-- 86
100 365 0 0 100 365 0 70 0:00:05 0:00:05 --:--:-- 70
100 365 0 0 100 365 0 58 0:00:06 0:00:06 --:--:-- 0
100 365 0 0 100 365 0 50 0:00:07 0:00:07 --:--:-- 0
100 365 0 0 100 365 0 44 0:00:08 0:00:08 --:--:-- 0
100 365 0 0 100 365 0 39 0:00:09 0:00:09 --:--:-- 0
100 365 0 0 100 365 0 37 0:00:09 0:00:09 --:--:-- 0
100 10.4M 0 10.4M 100 365 1016k 34 0:00:10 0:00:10 --:--:-- 2493k
100 11.6M 0 11.6M 100 365 1128k 34 0:
00:10 0:00:10 --:--:-- 3547k
STANDARD OUTPUT:
Maintenance mode enabled
Deleting increment at time:
<snip>
ls -A ${local_backup_location}/nextcloud-data/
それでは、この場合、コマンドがエラー出力を生成するのはなぜですか。ディレクトリが空であることをテストする別の信頼できる方法も許可されていますが、このコマンドがエラー出力を生成するように見える理由も説明したいと思います。
編集:Cronic stdoutを追加set -ex
set -ex
一部のコメント作成者は非常に長い実際のスクリプト全体を要求しましたが、Cronicはスクリプトの上部で使用されているスクリプトの実際の標準出力を報告します。エラー出力は呼び出し直後に発生するので、ls -A /mnt/reos-storage-2/backups/nextcloud-data/
エラー出力はこのコマンドの結果であると思います。
+ rdiff-backup --ssh-no-compression /var/www/nextcloud /mnt/reos-storage-2/backups/nextcloud/
+ ls -A /mnt/reos-storage-2/backups/nextcloud-data/
+ [ 67cf481e-62a3-1039-8bf2-05805d214bca
<removed>
appdata_ocgcv9nemegb
<removed>
<removed>
<removed>
<removed>
files_external
flow.log
flow.log.1
__groupfolders
.htaccess
index.html
<removed>
<removed>
nextcloudadmin
nextcloud-db.bak
nextcloud.log
nextcloud.log.1
.ocdata
<removed>
<removed>
rdiff-backup-data
<removed>
Test_User
<removed>
updater.log
updater-ocgcv9nemegb ]
+ rdiff-backup --remove-older-than 6M --force /mnt/reos-storage-2/backups/nextcloud-data/
+ date +%Y-%m-%d %T
+ echo [2021-04-21 03:23:38] Starting nextcloud data backup
ベストアンサー1
+ [ 67cf481e-62a3-1039-8bf2-05805d214bca <削除> [...] アップデータログ アップデータ-ocgcv9nemegb]
さて、コマンドです。 /outputに改行が含まれているため、/outputは複数行に分割set -x
されます。 (Bashはいくつかの引用符を使用して印刷しますが、Dashはそうではありません。)xtrace
ls
xtrace
デフォルトでは、出力はstderrに送信され、通常のエラー出力と同様に、Cronicは行の先頭の+
マーカーを見て出力を切り離そうとしますxtrace
。ここで失敗したのは、ファイル名が次のようになると思います。定期的なエラー出力。
cronicがすることは基本的に次のとおりです。
PATTERN="^${PS4:0:1}\\+${PS4:1}" if grep -aq "$PATTERN" $TRACE then ! grep -av "$PATTERN" $TRACE > $ERR
無効にすることもxtrace
この問題を解決する1つの方法ですが、cronicがそれを非常によくサポートしているので残念です。
代わりに、別の方法を使用してディレクトリが空であることを確認することをお勧めします。
一貫性を保つために、ls -A
出力をパイプしてwc
そこにある文字数を計算できます。
if [ "$(ls -A "${local_backup_location}/nextcloud-data/" | wc -c)" -gt 0 ]; then
echo "directory not empty"
fi
またはgrep
:
if ls -A "${local_backup_location}/nextcloud-data/" | grep -q .; then
echo "directory not empty";
fi
ディレクトリが空であることを確認することはシェル自体内で他の方法で行うことができますが、すべての極端なケースを処理するのは面倒です。たとえば、参照してください。 空のディレクトリの移植性チェック