mardi 26 mai 2020

bash: assignment AND condition test in nested statement?

My idea is some compact code that uses the value of an expression twice in one nested statement

  • for an assignment to a variable and

  • a condition test of the variable's new value against another value

The questions are:

  1. Is this compact form generally possible in bash

  2. If it is, do I have to fear negative side effects

You can certainly make the assignment before:

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

--> Works!

If variable 'bus_connection' is only needed in case of success you also can do:

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

--> Also works! (Don't use 'local' on the command line!)

In C(++) and some other compiled high level languages you can do it more compact (let's suppose a c function 'lsblk'):

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

In bash I tried:

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

--> Error message and wrong result!

I tested with an integer case and found:

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

--> Works! Negative side effects?

Analog:

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

--> No error message but wrong result!

$ echo "$bus_connection"
0

--> Ah, obviously bash treats variable 'bus_connection' as of type integer now.

Any suggestions for strings?

Aucun commentaire:

Enregistrer un commentaire