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은 오류를 추적되지 않는 오류 출력 또는 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는 그렇지 않습니다.)xtracels

기본적으로 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개의 항목: ...).

관련 정보