알 수 없는 이유로 쉘 스크립트가 일찍 종료됩니다.

알 수 없는 이유로 쉘 스크립트가 일찍 종료됩니다.

백업을 위해 다음 스크립트를 사용하고 있습니다.보그 백업. 그런데 이상한 문제가 생겼습니다

스크립트의 다음 부분은 실행되지 않습니다. 스크립트는 다음과 같고 출력은 다음과 같습니다.

스크립트:

#!/bin/bash                                                                                                                                                  

set -ex
set -o pipefail
export SERVER="myserver"
CLEVEL=zlib,9
. /home/faheem/.keychain/${HOSTNAME}-sh

#borg init -e none faheem@$SERVER:/mnt/backup-test                                                                                                         
borg create -c 30 --compression $CLEVEL --stats faheem@ramnode:/mnt/backup-test::`hostname`-`date +%Y-%m-%d:%H.%M`  /home/faheem/test-borg                   
{ borg check faheem@$SERVER:/mnt/backup-test 2>&1 1>&3 | tr '\r' '\n' | grep -Ev "^Remote:\s*(Checking segments.*)?$" 1>&2; } 3>&1
mapfile -t testarchives < <(borg list --short faheem@$SERVER:/mnt/backup-test)
borg extract -n "faheem@$SERVER:/mnt/backup-test"::"${testarchives[-1]}"

산출:

+ set -o pipefail
+ export SERVER=ramnode
+ SERVER=ramnode
+ CLEVEL=zlib,9
+ . /home/faheem/.keychain/orwell-sh
++ SSH_AUTH_SOCK=/tmp/ssh-F7Uzg6CeQoTY/agent.5660
++ export SSH_AUTH_SOCK
++ SSH_AGENT_PID=5661
++ export SSH_AGENT_PID
++ hostname
++ date +%Y-%m-%d:%H.%M
+ borg create -c 30 --compression zlib,9 --stats faheem@ramnode:/mnt/backup-test::orwell-2016-09-16:05.04 /home/faheem/test-borg
+ borg check faheem@ramnode:/mnt/backup-test
+ tr '\r' '\n'
+ grep -Ev '^Remote:\s*(Checking segments.*)?$'

따라서 마지막 두 줄은 실행되지 않습니다. 하지만 이전 줄을 주석 처리하면 이 두 줄이 실행됩니다. 무엇이 잘못되고 있는지 아는 사람이 있나요?

업데이트: grep을 꺼내면(즉, 교체)

{ borg check faheem@$SERVER:/mnt/backup-test 2>&1 1>&3 | tr '\r' '\n' | grep -Ev "^Remote:\s*(Checking segments.*)?$" 1>&2; } 3>&1

그리고

{ borg check faheem@$SERVER:/mnt/backup-test 2>&1 1>&3 | tr '\r' '\n' 1>&2; } 3>&1

알겠어요

+ set -o pipefail
+ export SERVER=ramnode
+ SERVER=ramnode
+ CLEVEL=zlib,9
+ . /home/faheem/.keychain/orwell-sh
++ SSH_AUTH_SOCK=/tmp/ssh-F7Uzg6CeQoTY/agent.5660
++ export SSH_AUTH_SOCK
++ SSH_AGENT_PID=5661
++ export SSH_AGENT_PID
++ hostname
++ date +%Y-%m-%d:%H.%M
+ borg create -c 30 --compression zlib,9 --stats faheem@ramnode:/mnt/backup-test::orwell-2016-09-17:03.18 /home/faheem/test-borg
+ borg check faheem@ramnode:/mnt/backup-test
+ tr '\r' '\n'
Remote: Checking segments 0.0%
Remote:                         
+ mapfile -t testarchives
++ borg list --short faheem@ramnode:/mnt/backup-test
+ borg extract -n faheem@ramnode:/mnt/backup-test::orwell-2016-09-17:03.18

이 줄은 일치할 수 없고 0이 아닌 값을 반환하는 패턴 Remote:에 해당합니까 ?grep

다음은 몇 가지 관련 질문입니다.

grep이 true/false를 반환할 수 있습니까? 아니면 다른 방법이 있습니까?

그리고

입력이 일치하지 않을 때 grep이 오류를 반환하지 않도록 방지

후자의 질문은 동일하지는 않더라도 비슷한 상황인 것 같습니다.

답변1

set -e, grep이 0이 아닌 값을 반환하는 경우(즉, 패턴이 일치하지 않음) 와 결합하면 pipefail파이프라인이 실패하고 스크립트가 중단된다는 의미입니다.

그래서 어느 쪽이든

  • 제거하다set -e
  • 제거하다pipefail
  • || truegrep항상 0이 반환되도록 세그먼트에 1을 추가합니다.

답변2

grep특정 패턴이 발견되었는지 여부에 따라 종료 상태를 설정하도록 설계되었으며, 경우에 따라오직이 목적을 위해 모든 출력이 억제됩니다. (이것이 -q로 전환하는 것입니다 grep.)

sed텍스트 스트림을 필터링하고 통과할 때 어떤 방식(보통 한 줄씩)으로 변환하도록 설계된 "스트림 편집기"입니다.

이 두 유틸리티 사이에는 중복되는 부분이 많지만 둘 다 특정 목적으로 사용됩니다. 이 경우 패턴이 발견되었는지 여부에는 관심이 없으며 텍스트 스트림을 전달하기 전에 필터링하기만 하면 됩니다. 이는 올바른 사용 사례이지만 sed그렇지 않습니다 grep.


sed -E '/^Remote:\s*(Checking segments.*)?$/d' delme.txt

이는 다음과 정확히 동일합니다.

grep -Ev '^Remote:\s*(Checking segments.*)?$' delme.txt

...와는 별개로grep패턴과 일치하는 행 외에 다른 행이 없으면 명령은 오류 종료 상태를 제공하며 sed그렇지 않습니다.

관련 정보