Linux shell脚本:仅当程序存在时才运行它,如果不存在则忽略它

Linux shell脚本:仅当程序存在时才运行它,如果不存在则忽略它

我正在编程一个Linux shell 脚本figlet仅当正确的工具(例如)是时,才会在执行期间打印状态横幅已安装(这是:可在系统上访问小路)。

例子:

#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"

我希望我的脚本能够运行没有错误即使当figlet未安装

什么可能是实用方法

答案1

我的解释是使用与工具同名的包装函数;在该函数中,执行真实工具(如果存在):

figlet() {
  if command -p figlet  >/dev/null 2>&1
    then 
      command figlet "$@"
    else
      :
    fi
}

然后你figlet arg1 arg2...的脚本就可以保持不变。

@Olorin 提出了一个更简单的方法:仅在需要时定义包装函数(如果该工具不存在):

if ! command -v figlet > /dev/null; then figlet() { :; }; fi

如果您希望figlet即使未安装 Figlet 也能打印参数,请调整 Olorin 的建议,如下所示:

if ! command -v figlet > /dev/null; then figlet() { printf '%s\n' "$*"; }; fi

答案2

你可以测试一下是否figlet存在

if type figlet >/dev/null 2>&1
then
    echo Figlet is installed
fi

答案3

在脚本开始时,检查是否figlet存在,如果不存在,则定义一个不执行任何操作的 shell 函数:

type figlet >/dev/null 2>&1 || figlet() { :; }

type检查是否figlet作为 shell 内置函数、别名或关键字存在,>/dev/null 2>&1丢弃 stdin 和 stdout,这样您就不会得到任何输出,如果不存在,则figlet() { :; }定义figlet为不执行任何操作的函数。

这样您就不必编辑使用 的脚本的每一行figlet,或者每次figlet调用时都检查它是否存在。

如果您愿意,您可以添加诊断消息:

type figlet >/dev/null 2>&1 || { echo 'figlet not installed.' ; figlet() { :; } ; }

作为奖励,由于您没有提及您正在使用哪个 shell,我相信这是符合 POSIX 标准的,因此它应该适用于大多数 shell。

答案4

另一种选择——我在项目自动配置脚本中看到的模式:

if [ -x /usr/bin/figlet ]
then
    FIGLET=/usr/bin/figlet
else
    FIGLET=:
fi

$FIGLET "Hello, world!"

根据您的具体情况,您甚至可以这样做,

if [ -x /usr/bin/figlet ]
then
   SAY=/usr/bin/figlet
elif [ -x /usr/local/bin/figlet ]
then
   SAY=/usr/local/bin/figlet
elif [ -x /usr/bin/banner ]
then
   SAY=/usr/bin/banner
else
   SAY=/usr/bin/echo
fi

$SAY "Hello, world!"

如果您不知道具体路径,可以尝试多个elif(见上文)来尝试已知位置,或者仅使用PATH始终解析命令:

if command -v figlet >/dev/null
then
    SAY=figlet
elif command -v banner >/dev/null
then
    SAY=banner
else
    SAY=echo
fi

一般来说,在编写脚本时,我更喜欢只调用我指定的特定位置的命令。我不喜欢最终用户可能在他们的PATH(也许是他们自己的)中投入的内容的不确定性/风险~/bin

例如,如果我正在为其他人编写一个复杂的脚本,该脚本可能会根据我正在调用的特定命令的输出来删除文件,那么我不想意外地拾取其中可能是~/bin也可能不是该命令的内容我期望。

相关内容