灵感来自这个答案:当我type -p
在命令提示符下运行时,如果命令存在,它会可靠地告诉我路径:
pi@raspberrypi:~ $ type -p less
/usr/bin/less
pi@raspberrypi:~ $ type -p asdf
pi@raspberrypi:~ $
但是,当在脚本中使用时,参数就好像-p
被解释为自身的命令。该命令似乎忽略了它作为其选项,因为结果中type
总是存在一些流氓文本。-p not found
它破坏了脚本的其余部分:
#!/usr/bin/sh
main() {
for mycommand in $1; do
echo Checking $mycommand
loc="$(type -p "$mycommand")"
echo $loc
if ! [ -f "$loc" ]; then
echo I think I am missing $mycommand
fi
done
}
main "less asdf"
脚本的输出:
Checking less
-p: not found less is /usr/bin/less
I think I am missing less
Checking asdf
-p: not found asdf: not found
I think I am missing asdf
你能帮我一下吗?是不是树莓派的外壳有什么问题导致了这个问题?
答案1
-p
不是该type
命令的标准选项。该type
实用程序本身,尽管标准在 POSIX 中是可选的(仅在实现 XSI 的系统上需要,尽管这是获得 UNIX 合规性认证所必需的)。
type
您可以使用代替command -v
来检查命令的可用性。无需检查其输出,command
将通过其退出状态告诉您是否成功找到该命令(无论它是在$PATH
、内置命令还是函数中找到的外部命令):
#!/usr/bin/sh -
main() {
for mycommand do
printf >&2 '%s\n' "Checking $mycommand"
if ! command -v -- "$mycommand" > /dev/null 2>&1; then
printf >&2 '%s\n' "I think I am missing $mycommand"
fi
done
}
main less asdf
command
是一个强制性的 POSIX 实用程序。该-v
选项曾经command
是可选的,但在最新版本的 POSIX 规范中不再是这样。
还请记住echo
不能用于显示任意数据,--
必须用于分隔选项和非选项,错误(以及一般诊断,包括进度/建议信息)最好应该转到 stderr。
然而,它是、、、和shells²type
内置支持的选项。在和中,它意味着在标准中搜索命令(例如返回的命令),在 中,它仅用于在 中搜索命令,而不是在别名/内置函数/函数中搜索命令。与 中相同,只是它也只打印找到的命令的路径。在(它曾经是;尽管不再记录但仍然受支持),如果命令是内置命令,则成功但不打印任何内容,并且仅在它是外部命令时像 ksh93 中那样打印路径。在 中,它的行为类似于bash
mksh
ksh93
busybox ash
zsh
yash
mksh
yash
$PATH
getconf PATH
zsh
$PATH
ksh93
bash
-path
type -p
busybox ash
command -v
sh
²至少在调用时或多或少符合标准语言的解释器实现sh
,尽管这并不妨碍它们在标准未指定行为的区域(如此处)支持对该语言的扩展。
答案2
#!/bin/sh
command="somecommand"
if [ "$(which "$command")" != "" ];
then
echo "command found"
else
echo "command not found"
fi