O script de shell sai cedo por razões não claras

1

Estou usando o seguinte script para fazer backup, usando o Borg Backup . Mas estou me deparando com um problema estranho

Parte do script abaixo não é executada. O script segue, então a saída

SCRIPT:

#!/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]}"

OUTPUT:

+ 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.*)?$'

Portanto, as duas últimas linhas não são executadas. Mas se eu comentar as linhas anteriores, essas duas linhas serão executadas. Alguém sabe o que está errado?

UPDATE: Se eu tirar grep (ou seja, substituir)

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

com

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

Eu obtenho

+ 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

A linha Remote: corresponde a grep que não corresponde ao padrão e retorna diferente de zero?

Aqui estão algumas perguntas relevantes:

O grep pode retornar true / false ou Existem métodos alternativos

e

Evite erros de devolução do grep quando a entrada não corresponder

A última questão parece ser uma situação semelhante, se não a mesma.

    
por Faheem Mitha 16.09.2016 / 01:36

2 respostas

3

O set -e significa que, se o grep retornar diferente de zero (ou seja, o padrão não é correspondido), isso combinado com pipefail significa que o pipe falha e faz com que o script seja abortado.

Então, ou

  • remover set -e
  • remover pipefail
  • Adicione um || true no segmento grep para garantir que sempre retorne zero
por 16.09.2016 / 01:42
1

grep é projetado para definir um status de saída de acordo com a existência ou não de um padrão específico e, em alguns casos, é usado somente para essa finalidade e qualquer saída é suprimida. (Esse é o propósito do -q mudar para grep .)

sed é o "Stream EDitor" e foi projetado para filtrar um fluxo de texto, convertendo-o de alguma forma (geralmente linha por linha) conforme ele passa.

Embora haja muita sobreposição entre esses dois utilitários, cada um deles tem uma finalidade específica. Nesse caso, evidentemente, você não está interessado em saber se o padrão é encontrado ou não, basta filtrar o fluxo de texto antes de transmiti-lo. Esse é um caso de uso adequado para sed , não para grep .

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

Este é o equivalente exato de:

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

... exceto que o comando grep fornecerá um status de saída de erro se não houver linhas além daquelas que correspondem ao padrão e sed não.

    
por 17.09.2016 / 02:37