Sop*_*rez 18 shell scripting executable
我编程的Linux shell脚本,将只有在合适的工具,比如它的执行过程中打印状态横幅figlet,被安装(是这样的:到达系统的路径)。
例子:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
Run Code Online (Sandbox Code Playgroud)
我想为我的脚本工作无差错,即使figlet在没有安装。
什么是实用的方法?
Jef*_*ler 35
我的解释是使用与工具名称相同的包装函数;在该函数中,如果存在,则执行真正的工具:
figlet() {
command -v figlet >/dev/null && command figlet "$@"
}
Run Code Online (Sandbox Code Playgroud)
然后你可以figlet arg1 arg2...在你的脚本中保持不变。
@Olorin 提出了一个更简单的方法:仅在我们需要时(如果该工具不存在)定义一个包装函数:
if ! command -v figlet > /dev/null; then figlet() { :; }; fi
Run Code Online (Sandbox Code Playgroud)
如果您希望在figlet未安装 figlet 的情况下打印参数,请按如下方式调整 Olorin 的建议:
if ! command -v figlet > /dev/null; then figlet() { printf '%s\n' "$*"; }; fi
Run Code Online (Sandbox Code Playgroud)
roa*_*ima 14
你可以测试看看是否figlet存在
if type figlet >/dev/null 2>&1
then
echo Figlet is installed
fi
Run Code Online (Sandbox Code Playgroud)
一种常见的方法是使用test -xaka [ -x。下面是一个取自/etc/init.d/ntpLinux 系统的示例:
if [ -x /usr/bin/lockfile-create ]; then
lockfile-create $LOCKFILE
lockfile-touch $LOCKFILE &
LOCKTOUCHPID="$!"
fi
Run Code Online (Sandbox Code Playgroud)
此变体依赖于了解可执行文件的完整路径。在/bin/lesspipe我找到了一个例子,它通过组合-x和which命令来解决这个问题:
if [ -x "`which bunzip`" ]; then bunzip -c "$1"
else echo "No bunzip available"; fi ;;
Run Code Online (Sandbox Code Playgroud)
这样就可以在不事先知道可执行文件中的位置PATH的情况下工作bunzip。
另一种选择——我在项目自动配置脚本中看到的一种模式:
if [ -x /usr/bin/figlet ]
then
FIGLET=/usr/bin/figlet
else
FIGLET=:
fi
$FIGLET "Hello, world!"
Run Code Online (Sandbox Code Playgroud)
在您的特定情况下,您甚至可以这样做,
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!"
Run Code Online (Sandbox Code Playgroud)
如果您不知道具体路径,您可以尝试多个elif(见上文)来尝试已知位置,或者只使用PATH始终解析命令:
if command -v figlet >/dev/null
then
SAY=figlet
elif command -v banner >/dev/null
then
SAY=banner
else
SAY=echo
fi
Run Code Online (Sandbox Code Playgroud)
一般来说,在编写脚本时,我更喜欢只在我指定的特定位置调用命令。我不喜欢最终用户可能放入PATH他们的~/bin.
例如,如果我正在为其他人编写一个复杂的脚本,这些脚本可能会根据我正在调用的特定命令的输出删除文件,我不想意外地从他们~/bin那里拿起一些可能是也可能不是命令的东西我期望。
在脚本开始时,检查是否figlet存在,如果不存在,定义一个什么都不做的 shell 函数:
type figlet >/dev/null 2>&1 || figlet() { :; }
Run Code Online (Sandbox Code Playgroud)
type检查是否figlet作为 shell 内置、函数、别名或关键字存在,>/dev/null 2>&1丢弃 stdin 和 stdout,因此您不会得到任何输出,如果它不存在,则figlet() { :; }定义figlet为一个什么都不做的函数。
这样您就不必编辑使用 的脚本的每一行,也不必在figlet每次figlet调用时检查它是否存在。
如果您愿意,可以添加诊断消息:
type figlet >/dev/null 2>&1 || { echo 'figlet not installed.' ; figlet() { :; } ; }
Run Code Online (Sandbox Code Playgroud)
作为奖励,由于您没有提到您使用的是哪个 shell,我相信这是 POSIX 兼容的,因此它应该适用于大多数 shell。