I have a script I run regularly using cron. I would like to get notified by email when these scripts fail. I do not wish to be notified every time they run and produce any output at all.
As such, I am using the script Cronic to run my jobs inside cron, which should mean only error output gets sent, and not just any output.
However, in one script I have a command like this:
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
The ls -A ${local_backup_location}/nextcloud-data/
is intended to test if a directory is empty. My problem is that this command seems to result in output which is recognized as error output cronic. Cronic defines an error as any non-trace error output or a non-zero result code. For example:
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>
So why does the command ls -A ${local_backup_location}/nextcloud-data/
produce error output in this case, and how can I prevent this? An alternative robust method to test if a directory is empty would be acceptable, but I would also like an explanation of why the command seems to produce error output.
EDIT: Adding Cronic stdout with set -ex
Some commenters have requested the actual whole script which is very long, but Cronic reports the actual stdout of the script and I use set -ex
at the top of the script. The error output happens immediately after the invocation of ls -A /mnt/reos-storage-2/backups/nextcloud-data/
which is why I believe the error output to be the result of this command.
+ 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
ls
. Are you in fact callingfind
? – Kusalananda Apr 23 '21 at 15:55]
twice and no actual error message. There's also output fromcurl
(?), but nocurl
command is shown. – Kusalananda Apr 23 '21 at 17:28custom
,gitea-db.sql
,log
) are out of sequence but the order of the remainder is reproducible under (at least)en_GB.UTF-8
. – Chris Davies Apr 23 '21 at 17:39#!/bin/bash
line and anyset -o errexit
lines etc, and also the cron command you use to launch it. If you think the problem is in the part you quoted, then leave just that, and post the results: the full script and the error output you get. And if the problem doesn't appear after you remove everything else, well, then the problem is somewhere else. – ilkkachu Apr 23 '21 at 19:25curl
. Does your script use that, or doesrdiff-backup
use it when running--remove-older-than
? As far as I can tell,rdiff-backup
does use thersync
libraries, but I can find no mention ofcurl
in connection with it. – ilkkachu Apr 26 '21 at 14:05set -e
at the top so all commands are echoed. The error output immediately follows thels -A
command so I made the assumption that it was responsible for this error output. Is this incorrect? – crobar Apr 26 '21 at 14:30set -x
? Doing so would definitely spam standard error with output. – Kusalananda Apr 26 '21 at 15:11set -x
I want the script to stop if there's an error of any kind – crobar Apr 26 '21 at 18:53set -x
prints all lines the shell runs (the ones starting with the plus).set -e
is the one that makes the shell exit if a command returns with an error. (Apart from when it doesn't, see e.g. http://mywiki.wooledge.org/BashFAQ/105 ) – ilkkachu Apr 26 '21 at 19:16