I'm trying to compare the state of more than two variables. The use-case is a script that, among other options, should select (or auto-select) only one of several "modes" based on available executables. A partial syntax diagram is:
[ [--fzf,-f]|[--rofi,-r]|[--dmenu,-d] ]
The variables are defined based on presence of command arguments, so, for example, if --fzf or -f are found on the command line arguments, an associated fzf variable is set to "1" indicating that the user wants to run the script in, for lack of better terms, fzf mode.
The && operator statement below addresses what happens if none of the command arguments is found on the command-line. Basically, if no "mode" was selected, then the script will auto-select one, and only one, mode to use in a hierarchical fashion.
The || operator statement below is supposed to address what happens if a mode is selected (by the user), but the underlying executable is not found.
Here is the original version for the && operator:
if [[ $fzf = 0 && $rofi = 0 ]]; then
if command_exists fzf; then
fzf=1
elif command_exists rofi; then
rofi=1
fi
fi
to
if [[ $fzf = 0 && $rofi = 0 && $dmenu = 0 ]]; then
if command_exists fzf; then
fzf=1
elif command_exists rofi; then
rofi=1
elif command_exists dmenu; then
dmenu=1
fi
fi
And lastly, here the original for the || operator:
if [[ $rofi = 1 || $fzf = 0 ]]; then
command_exists rofi || die "Could not find rofi in \$PATH"
menu="$rofi_cmd"
elif [[ $fzf = 1 || $rofi = 0 ]]; then
command_exists fzf || die "Could not find fzf in \$PATH"
menu="$fzf_cmd"
else
die "Could not find either fzf or rofi in \$PATH"
fi
to
if [[ $rofi = 1 || $fzf = 0 || $dmenu = 0 ]]; then
command_exists rofi || die "Could not find rofi in \$PATH"
menu="$rofi_cmd"
elif [[ $fzf = 1 || $rofi = 0 || $dmenu = 0 ]]; then
command_exists fzf || die "Could not find fzf in \$PATH"
menu="$fzf_cmd"
elif [[ $dmenu = 1 || $rofi = 0 || $fzf = 0 ]]; then
command_exists dmenu || die "Could not find dmenu in \$PATH"
menu="$dmenu_cmd"
else
die "Could not find either fzf or rofi or dmenu in \$PATH"
fi
Which doesn't seem to throw any error, but i suspect that this is neither the correct way to do this, and probably doesn't work as expected (as it seems to report wrong values when using -x and seeing it's output).
I'm aware of post such as this one, but i didn't (yet) found examples with more than two variables (like what I tried to do above).
The above original part were taken from this script. I'm basically trying to add support for dmenu since it only support rofi and fzf (as showed above).
Here the full modified script. It need password-store as dependencies.
I'm using Bash 5.0.3.
How do i use the && and || operators with more than two variables correctly?
diesupposed to be? If you're thinking of something like Perl'sdie(), that doesn't exist in bash as far as I know. You can useexitinstead. – terdon Sep 23 '20 at 18:23bashbut i guess I'll add it in my post too. @kbulgrien – Nordine Lotfi Sep 23 '20 at 18:44one = 1; two=2; four=$4; $ if [[ $one = 1 && $two = 2 && $four = 5 ]]; then echo works; fiThe question needs to add more information if someone is supposed to be able to help figure out what you are missing. I.e. Show us a snippet of the debug with -x or other things you have done to troubleshoot. Regardless, the title of the question isn't a good fit. Please add more detail to get better help. Version of BASH conceptually could be relevant too. – kbulgrien Sep 23 '20 at 18:57dmenu. What we need to know is what you are expecting from all theseifstatements. What do you think they are doing? You say they give "wrong values" but we have no idea what the "right" value would be. For instance, if$dmenuis0, your current version will always default tomenu="$rofi_cmd", no matter what value$fzfor$rofihave. Is that what you want? it could be, we have no way of knowing. – terdon Sep 23 '20 at 20:02