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은 오류를 추적되지 않는 오류 출력 또는 0이 아닌 결과 코드로 정의합니다. 예를 들어:
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
이 문제를 해결하는 한 가지 방법이지만, 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
디렉토리가 비어 있는지 확인하는 것은 셸 자체 내에서 다른 방법으로 수행할 수 있지만 모든 극단적인 경우를 처리하는 것은 번거로울 수 있습니다. 예를 들어 참조하십시오. 빈 디렉토리에 대한 이식성 검사
답변2
$gitea_backup_dir
존재하지 않거나 ls
어떤 식으로든 불쾌한 경우 ls
오류 메시지가 기록됩니다 STDERR
.
2>/dev/null
명령에 추가하여 전체 오류 스트림을 삭제할 수 있습니다.
IMHO 더 좋은 방법은 다음과 같습니다.
if ([[ -d "$gitea_backup_dir" ]] && \
[[ $(stat --format="%h" "$gitea_backup_dir") -gt 2 ]] ) ; then
echo "Nonempty"
else
echo "Empty"
fi
먼저 디렉토리가 존재하는지 확인한 다음 디렉토리의 하드 링크 수(디렉토리의 파일 및 하위 디렉토리 항목 수)가 2보다 큰지 확인하십시오(디렉토리 당 최소 2개의 항목: .
및 ..
).