我如何使用 && 和 || 具有两个以上变量的运算符正确吗?

Nor*_*tfi 0 bash test

我正在尝试比较两个以上变量的状态。用例是一个脚本,除其他选项外,它应该根据可用的可执行文件仅选择(或自动选择)几种“模式”中的一种。部分语法图是:

 [ [--fzf,-f]|[--rofi,-r]|[--dmenu,-d] ]
Run Code Online (Sandbox Code Playgroud)

变量是基于命令参数的存在而定义的,因此,例如,如果在命令行参数中找到--fzf或,则-f关联的fzf变量设置为“1”,表示用户希望在其中运行脚本,因为缺少更好的条款,fzf mode

下面的&&运算符语句解决了在命令行中找不到任何命令参数时会发生的情况。基本上,如果未选择“模式”,则脚本将自动选择一种且仅一种模式以分层方式使用。

下面的||operator 语句应该解决如果(由用户)选择了一种模式,但未找到底层可执行文件时会发生什么。

这是 && 运算符的原始版本:

 [ [--fzf,-f]|[--rofi,-r]|[--dmenu,-d] ]
Run Code Online (Sandbox Code Playgroud)

if [[ $fzf = 0 && $rofi = 0 ]]; then
        if command_exists fzf; then
            fzf=1
        elif command_exists rofi; then
            rofi=1
        fi
    fi
Run Code Online (Sandbox Code Playgroud)

最后,这里是 || 的原文 操作员:

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这似乎没有引发任何错误,但我怀疑这既不是正确的方法,也可能无法按预期工作(因为它在使用-x和查看输出时似乎报告了错误的值)。

我所知道的岗位,如一个,但我没有(还)发现的例子有两个以上的变量(如我尝试了上述这样做)。

以上原始部分取自脚本。我基本上是在尝试添加对 的支持,dmenu因为它只支持rofifzf(如上所示)。

这里是完整的修改脚本。它需要password-store作为依赖项。

我正在使用 Bash 5.0.3。

我如何使用 && 和 || 具有两个以上变量的运算符正确吗?

ilk*_*chu 5

如果用户只应该选择众多中的一个,我只会使用一个变量来保存选择,删除每个选项的变量。无论如何,我们并不真正关心所有的组合,我们只想要三个中的一个,另一个是“未设置/默认”。

所以:

#!/bin/sh
cmd=             # empty value for default
case "$1" in
    --rofi|-r)  cmd=rofi ;;
    --fzf|-f)   cmd=fzf ;;
    --dmenu|-d) cmd=dmenu ;;
esac

if [ -z "$cmd" ]; then
    echo "no command set, looking for default"
    if command_exists fzf; then
        cmd=fzf
    elif
        ...
    fi
fi

echo "running with command $cmd"
# actually do something
Run Code Online (Sandbox Code Playgroud)

在这里,选择的模式存储在cmd. 我实际上甚至没有给用户提供两个命令的可能性,只有第一个参数被读取以获取标志。现在,如果你使用getoptor getopts,那并没有真正成功,但我们可以在设置之前检查模式是否已经设置(再次)。

#!/bin/sh
error_if_cmd_set() {
    if [ -n "$1" ]; then
        echo "command already set"
        exit 1
    fi
}
cmd=
for arg in "$@"; do
    case "$1" in
        --rofi|-r)  error_if_cmd_set "$cmd"; cmd=rofi ;;
        --fzf|-f)   error_if_cmd_set "$cmd"; cmd=fzf ;;
        --dmenu|-d) error_if_cmd_set "$cmd"; cmd=dmenu ;;
    esac
done
# ...
echo "using command $cmd"
Run Code Online (Sandbox Code Playgroud)