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

bash: assignment AND condition test in nested statement?

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

问题是:

  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

--> 有效!

如果变量 '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' 视为整数类型。

对字符串有什么建议吗?

Is this compact form generally possible in 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 将第一个参数分配给第二个参数,并使用 return 退出状态 test

test_and_assign() {
   declare -n _test_and_assign_ref=
   shift
   _test_and_assign_ref=""
   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=$(...) 的代码片段一样,忽略了命令替换的退出状态。