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?
die
supposed to be? If you're thinking of something like Perl'sdie()
, that doesn't exist in bash as far as I know. You can useexit
instead. – terdon Sep 23 '20 at 18:23bash
but 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; fi
The 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 theseif
statements. 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$dmenu
is0
, your current version will always default tomenu="$rofi_cmd"
, no matter what value$fzf
or$rofi
have. Is that what you want? it could be, we have no way of knowing. – terdon Sep 23 '20 at 20:02