Bash 检查多个单词以匹配一个单词

Bash check multiple word to match one word

我有一个变量 BACKUP_STATUS 其中包含许多 SUCCESS 个单词

[ryt: i9]: echo $BACKUP_STATUS
SUCCESS SUCCESS SUCCESS SUCCESS SUCCESS

问题: 我想检查一下,如果变量中的这些词之一更改为其他词,则会出现错误 我这样试试

[[$BACKUP_STATUS = "SUCCESS"]] && echo true || echo false

但抛出错误

您可以使用带有测试命令的正则表达式来搜索是否找到“NO_SUCCESS”字符串

$ SUC="SUCCESS SUCCESS SUCCESS SUCCESS SUCCESS"
$ NSUC="SUCCESS SUCCESS SUCCESS SUCCESS NO_SUCCESS"
$ [[ $SUC =~ .*NO_SUCCESS.* ]] && echo "something wrong" || echo "everything is ok"
everything is ok
$ [[ $NSUC =~ .*NO_SUCCESS.* ]] && echo "something wrong" || echo "everything is ok"
something wrong

试试这个:

[[ $(tr ' ' '\n' <<<"$BACKUP_STATUS" | sort -u) == SUCCESS ]] && echo true || echo false

怎么样

if [[ " $BACKUP_STATUS" == *[^\ ]SUCCESS* || "$BACKUP_STATUS " == *SUCCESS[^\ ]* ]]
then
  echo unexpected status found
else
  echo only successes
fi 

这个想法是搜索一个在 SUCCESS 前面或后面有东西的词。这有点笨拙,但我找不到将两个条件合二为一的方法。

另一种可能是使用循环:

error=0
for statusword in $BACKUP_STATUS
do
  if [[ $statusword != SUCCESS ]]
  then
    echo Unexpected status: $statusword
    error=1
    break
  fi
done
if (( error == 0 ))
then
  # all SUCCESS
  ...
fi
      

两种解决方案都可以在不创建子进程的情况下使用。

我喜欢为此扩展的 globbing 和参数解析。

$:  echo "[$BACKUP_STATUS]" # value with a fail
[ SUCCESS SUCCESS SUCCESS SUCCESS SUCCESS NO_SUCCESS ]
$: shopt -s extglob         # set extended globbing

$: echo "[${BACKUP_STATUS//*( )SUCCESS*( )/}]"
[NO_]
$: [[ -z "${BACKUP_STATUS//*( )SUCCESS*( )/}" ]] && echo ok || echo no
no

$: BACKUP_STATUS=" SUCCESS SUCCESS SUCCESS SUCCESS SUCCESS " # no fails
$: echo "[${BACKUP_STATUS//*( )SUCCESS*( )/}]"
[]
$: [[ -z "${BACKUP_STATUS//*( )SUCCESS*( )/}" ]] && echo ok || echo no
ok

扩展的 globbing 让你有零个或多个空格。
${BACKUP_STATUS//*( )SUCCESS*( )/} 表示 return $BACKUP_STATUS 的值,每次出现 SUCCESS 前后都有或没有空格被删除。

如果有任何遗留问题,则它不是 SUCCESS return,因此 [[ -z ... ]] 检查零长度 return,因为所有成功。

这不需要产生任何外部过程。只是 Bash.