Shell 脚本因不明原因提前退出

Shell 脚本因不明原因提前退出

我正在使用以下脚本进行备份,使用博格备份。但我遇到了一个奇怪的问题

下面的脚本的一部分不执行。脚本如下,然后是输出

脚本:

#!/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

Remote:行是否对应于grep无法匹配模式并返回非零?

以下是几个相关问题:

grep 可以返回 true/false 还是有其他方法

当输入不匹配时避免 grep 返回错误

后一个问题似乎是类似的情况,即使不是相同的。

答案1

set -e意味着如果 grep 返回非零(即模式不匹配),那么与 结合pipefail意味着管道失败并导致脚本中止。

所以要么

  • 消除set -e
  • 消除pipefail
  • || true在段中添加一个grep以确保始终返回零

答案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不会。

相关内容