如何检查 bash 脚本中的依赖关系

问题描述 投票:0回答:7

我想检查系统上是否安装了nodejs。我收到此错误:

错误:未找到命令。

我该如何修复它?

#!/bin/bash

if [ nodejs -v ]; then
echo "nodejs found"
else
echo "nodejs not found"
fi
linux bash
7个回答
24
投票

您可以使用

command
bash 内置:

if command -v nodejs >/dev/null 2>&1 ; then
    echo "nodejs found"
    echo "version: $(nodejs -v)"
else
    echo "nodejs not found"
fi

2
投票

命令的名称是

node
,而不是
nodejs

将命令的路径返回到标准输出(如果存在)

if [ $(which node 2>/dev/null) ]; then
  echo "nodejs found"
else
  echo "nodejs not found"
fi

2
投票

这不是 OP 所要求的(大约 3 年前!),但对于任何想要检查多个依赖项的人来说:

#!/bin/bash
echo -n "Checking dependencies... "
for name in youtube-dl yad ffmpeg
do
  [[ $(which $name 2>/dev/null) ]] || { echo -en "\n$name needs to be installed. Use 'sudo apt-get install $name'";deps=1; }
done
[[ $deps -ne 1 ]] && echo "OK" || { echo -en "\nInstall the above and rerun this script\n";exit 1; }

这就是它的工作原理。首先,我们打印一行,表示我们正在检查依赖关系。第二行启动一个“for name in...”循环,在其中我们放置要检查的依赖项,在本例中我们将检查 youtube-dl、yad 和 ffmpeg。循环开始(以“do”开头),下一行使用 bash 命令“which”检查每个命令是否存在。如果依赖项已安装,则不执行任何操作,我们会跳到循环中的下一个命令。如果确实需要安装,则会打印一条消息,并将变量“deps”设置为 1(deps = 依赖项),然后我们继续执行下一个命令进行检查。检查完所有命令后,最后一行通过检查 deps 变量来检查是否需要任何依赖项。如果未设置,则会将“确定”附加到最初显示“检查依赖项...”的行并继续(假设这是脚本的第一部分)。如果设置了,它会打印一条消息,要求安装依赖项并重新运行脚本。然后退出脚本。

echo 命令看起来很复杂,但它们对于在终端上提供干净的输出是必要的。这是一个屏幕截图,显示第一次运行时不满足依赖关系,但第二次运行时满足依赖关系。

Bash dependency check script screen print

PS 如果将其另存为脚本,则需要位于与脚本相同的目录中并输入 ./{name_of_your_script} 并且它需要可执行。


1
投票

您可以通过

检查程序或函数是否存在
type nodejs &>/dev/null || echo "node js not installed"

但是,这里有更复杂的解释。


0
投票

我正在考虑这个问题,想出了几个版本,然后上网看看其他人怎么说,最后就到这里了。虽然是老帖了,不过我还是来回答一下我的想法吧

首先回答OP原来的问题:

How can i fix it?

if node -v &>/dev/null; then
    echo "nodejs found"
else
    echo "nodejs not found"
fi

如果您只是检查节点是否工作,这就可以了。但这不是一种非常通用的方法。

另一种方法是在循环中使用命令并收集缺少的依赖项(在此示例中查找命令

kind
kubectl
)。

for app in kind kubectl; do command -v "${app}" &>/dev/null || not_available+=("${app}"); done
(( ${#not_available[@]} > 0 )) && echo "Please install missing dependencies: ${not_available[*]}" 1>&2 && exit 1

或者不太简洁地表达:

unset not_available # script safety, however not necessary.

for app in kind kubectl; do
    if ! command -v "${app}" &>/dev/null; then
        not_available+=("${app}")
    fi
done

if (( ${#not_available[@]} > 0 )); then
    echo "Please install missing dependencies: ${not_available[@]}" 1>&2
    exit 1
fi

然后我想我想要一种没有循环的方法来做同样的事情,所以想出了这个:

not_installed=$(command -V kind kubectl 2>&1 | awk -F': +' '$NF == "not found" {printf "%s ", $(NF-1)}')
[[ -n ${not_installed} ]] && echo "Please install missing dependencies: ${not_installed}" 1>&2 && exit 1

command -V
可以获取任意数量的条目并将结果发布回stdout和stderr(尽管我将两者重定向到stdout以供下一个要解析的命令使用)。

awk
将字段分隔符设置为
<colon><one or more space>
,表示为
: +
。如果最后一个字段包含“未找到”,则打印倒数第二个字段,即未安装的命令的名称。

最后,如果变量包含任何数据,则向

stderr
exit
脚本报告缺少哪些依赖项!


您可以用一百万种方式进行依赖性检查,但这里有一些更普遍适用的替代方案,并且不会太长,同时仍然易于遵循。 :]


0
投票

使用 Scooby-2

的函数进行优化的答案
checkdep() {
    local args=("$@")
    deps=0
    for name in "${args[@]}"; do
        [[ $(command -v $name 2>/dev/null) ]] || { cecho -y "$name" -r " needs to be installed.";deps=1;}
    done
    [[ $deps -ne 1 ]] && cecho -g "All depedencies fulfilled" || { cecho -r "\nInstall the above and rerun this script\n"; }
}

checkdep yad ffmpeg grep


-1
投票

如果您只想检查某个命令是否存在,请使用哪个命令。如果调用命令,它会返回补丁,如果没有找到,则不返回任何内容

if [ "$(which openssl)" = "" ] ;then
echo "This script requires openssl, please resolve and try again."
exit 1
fi
© www.soinside.com 2019 - 2024. All rights reserved.