bash: 嵌套语句中的赋值和条件测试?

问题描述 投票:-1回答:1

我想找的是一行紧凑的代码,在一个嵌套语句中两次使用表达式的值。

  • 赋值的变量

  • 对变量的新值和另一个值进行条件测试。

问题是。

  1. 这种紧凑的形式在bash中是否普遍可行?

  2. 如果可以,我是否需要担心负面的副作用(意外的结果)?

你当然可以在之前做任务。

$ local bus_connection="$(lsblk -dn -o TRAN /dev/sdd)"
$ test "$bus_connection" = "usb" || { echo "not usb"; exit 1 }
$ echo "$bus_connection"
usb

--> Works!

如果变量'bus_connection'只是在成功的情况下需要,你也可以这样做。

$ test "$(lsblk -dn -o TRAN /dev/$DEVICE)" = "usb" \
    && local bus_connection="usb" \
    || { echo "not usb"; exit 1 }
$ echo "$bus_connection"
usb

--> 也可以!(不要在命令行中使用'local'!)。

在C(++)和其他一些编译过的高级语言中,你可以做得更紧凑(假设一个c函数'lsblk')。

if( ( bus_connection = lsblk( ... ) ) == "usb" ) ; else {printf("not usb"); exit 1;}

在bash中,我试过:

$ test $(bus_connection="$(lsblk -dn -o TRAN /dev/sdd)") = "usb" || echo "not usb" 
bash: test: =: unary operator exspected.
not usb

--> 错误信息和错误结果!

我用整数情况进行了测试,发现。

$ sum=0
$ result=12
$ test $((sum=$sum+$result)) -gt 20 && echo "true"
$ test $((sum=$sum+$result)) -gt 20 && echo "true"
true

--> 工作!负面的副作用?

模拟。

$ test $((bus_connection="$(lsblk -dn -o TRAN /dev/sdd)")) = "usb" || echo "not usb"
not usb

--> 没有错误信息,但结果是错误的!

$ echo "$bus_connection"
0

--> 啊,显然bash现在把变量'bus_connection'当作整数类型了。

对于字符串有什么建议吗?

bash if-statement nested variable-assignment side-effects
1个回答
2
投票

这种紧凑的形式在bash中一般可以实现吗

不,不是的,至少没有自定义代码来处理。命令替换是在子shell中运行的--在父shell中看不到变化。算术扩展只进行算术运算--所有的字符串都被转换为数字(就像通过 atoi()/strtol()),如果没有扫描到数字,则转换为0。

通常的方法是在变量上赋值一个 && 后面是test - 允许检查命令的退出状态并获取结果。

if ! {
     bus_connection="$(lsblk -dn -o TRAN /dev/sdd)" &&
     test "$bus_connection" = "usb"
}; then
   echo "not usb"
   exit 1
fi

或者直接忽略命令的退出状态 lsblk:

if
   bus_connection="$(lsblk -dn -o TRAN /dev/sdd)"
   ! test "$bus_connection" = "usb"
then
   echo "not usb"
   exit 1
fi

不过你也可以自己写一个函数,使用bash namereference把第一个参数分配给第二个参数,然后用以下语句返回 test的退出状态。

test_and_assign() {
   declare -n _test_and_assign_ref=$1
   shift
   _test_and_assign_ref="$1"
   test "$@"
}

$ test_and_assign bus_connection "$(echo 123)" = "usb"
$ echo "$? $bus_connection"
1 123
$ test_and_assign bus_connection "$(echo usb)" = "usb"
$ echo "$? $bus_connection"
0 usb

请注意,在这里,就像在你的第一个代码片段中一样 local bus_connection=$(...)忽略命令替换的退出状态。

© www.soinside.com 2019 - 2024. All rights reserved.