ls -A のエラー出力によりエラーが出力されます。なぜですか?

ls -A のエラー出力によりエラーが出力されます。なぜですか?

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はそうではありません。)xtracels

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

ディレクトリが空であることを確認することはシェル自体内で他の方法で行うことができますが、すべての極端なケースを処理するのは面倒です。たとえば、参照してください。 空のディレクトリの移植性チェック

おすすめ記事