运行与[[]]操作符同一行的命令



我试图在Bash中使用[[]]操作符并且严重失败。我的脚本是:

#!/bin/bash
# Test driver for the ProtectDatae script 
set -o xtrace
# [[ -z "$1" ]] || source="$1" && source=""
if [[ -z "%1" ]]
then
source=""
else
source=$1
fi
[[ -z "$2" ]] || target="$2" && target="" # This does not work
[[ -z "$3" ]] || sourceBackup="$3" && sourceBackup="/tmp/sourcebackup" # This does not work
source cmd.sh  # Get a function to run a Linux command
if [[ -e "$sourceBackup" && "$sourceBackup" -ne "" ]]
then
# If a source backup directory is specified then get rid of any old directory and make a new backup
# and verify it. If OK, make the source directory be the source backup directory
# otherwise work directly in the source directory
if [[ -e "$sourceBackup" ]]
then
cmd "sudo rm -R $sourceBackup" "empty backup directory $sourceBackup failed"
cmd "cp -apu $source $sourceBackup" "backup home directory"
cmd "diff -aprN ~/$source/* $sourceBackup" "bad backup in $sourceBackup"
source="$sourceBackup"
fi
fi
exit 0

命令调用是./TestProtectData.sh "~" /tmp/jfghome /tmp/jfgbackup

xtrace的结果是:
+ source='~'
+ [[ -z /tmp/jfghome ]]
+ target=/tmp/jfghome
+ target=""
+ [[ -z /tmp/jfgbackup ]]
+ sourceBackup=/tmp/jfgbackup
+ sourceBackup=/tmp/sourcebackup
+ source cmd.sh
+ [[ -e /tmp/sourcebackup ]]
+ exit 0

下面一行发生的是错误。两个替代方案似乎都被执行了,变量最终设置不正确:

[[ -z "$2" ]] || target="$2" && target=""

我试了两个订单&&和||它们都给出了相同的结果,变量target被设置为空白。在下一行中,将变量sourceBackup设置为第二个备选项时会发生类似的事情,并且两个备选项似乎都被执行。如果我使用if then结构,它可以工作。我做错了什么?

我做错了什么?

您的预期逻辑与您正在使用的bash结构不匹配。这条线:

[[ -z "$2" ]] || target="$2" && target="" # This does not work

分解为平均if 2 is not empty set target to $2. If that command succeeds, set target to ""&&左边的命令总是会成功——-z测试成功或者target="$2"测试成功。因此,target=""总是在最后运行。

您可以使用if ... ; then ...; else ...; fi或查看以下方法在bash中实现三元操作符,包括:

#!/bin/bash -e
[[ -z "$3" ]] && sourceBackup="/tmp/sourcebackup" || sourceBackup="$3"
echo $sourceBackup
% ./t.sh 1 2 3                                                                                                                                                            
3

这里,如果-z测试成功,我们将sourceBackup设置为默认值。如果测试失败,$3不为空,我们将sourceBackup设置为$3

重申一下,这是而不是与三级操作符完全相同。但是如果你的顺序是正确的,它就会起作用。

普通赋值(foo=bar)总是将状态码设置为0,因此在target被设置为$2之后,它立即被设置为空。我将从把逻辑颠倒过来开始:

target= # Set to empty string
[[ -z $2 ]] && target=$2

然而,这是多余的。你可以直接写

target=$2

不做任何[[...]]-test。如果第二个参数为空,则target也将为空。如果不为空,target将获取该值。

有一点需要考虑:如果您决定打开set -u,以捕获未初始化的变量,如果没有第二个参数,target=$2将中止脚本。因此,您也可以写

target=${2:-}

告诉bash缺少的参数是OK的,应该作为空字符串处理。

即使是冗余的,如果不是打开-u,使用${2:-}显式显示你的意图,使你的程序更易于维护。

相关内容

  • 没有找到相关文章

最新更新