bash: 嵌套语句中的赋值和条件测试?
bash: assignment AND condition test in nested statement?
我正在寻找的是在一个嵌套语句中两次使用表达式值的紧凑代码行
对于变量的赋值和
变量的新值与另一个值的条件测试
问题是:
这种紧凑形式在bash中普遍可行吗?
如果是,我是否需要担心负面影响(意想不到的结果)?
你当然可以做之前的作业:
$ 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=$(...)
的代码片段一样,忽略了命令替换的退出状态。
我正在寻找的是在一个嵌套语句中两次使用表达式值的紧凑代码行
对于变量的赋值和
变量的新值与另一个值的条件测试
问题是:
这种紧凑形式在bash中普遍可行吗?
如果是,我是否需要担心负面影响(意想不到的结果)?
你当然可以做之前的作业:
$ 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=$(...)
的代码片段一样,忽略了命令替换的退出状态。