思路

1.$PATH 为 : 分隔的文件夹路径字符串
2.将 IFS 修改为 : 后,for 循环可每次返回一个文件夹路径,并遍历整个 $PATH
2.1.Shell中的IFS解惑
3.if [ -x ] 判断路径是否存在

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/bin/bash
# inpath -- 验证指定程序是否有效,或者能否在 PATH 目录列表中找到

function in_path()
{
# 尝试在环境变量 PATH 中寻找给定的命令,找到返回 0,无则返回 1。
# !注意 该函数会临时修改 IFS (内部字段分隔符),函数执行完毕时会将其恢复原状。

cmd=$1
ourpath=$2
result=1
oldIFS=$IFS
IFS=":"

for directory in $ourpath
do
if [ -x "$directory"/"$cmd" ] ; then # -x 检查 cmd 路径是否存在
result=0 # 执行到此处表明已经找到该命令
fi
done

IFS=$oldIFS
return $result
}

function checkForCmdInPath()
{
var=$1

if [ "$var" != "" ] ; then
# 如果传入的命令带绝对路径
if [ "${var:0:1}" = "/" ] ; then # 变量切分语法 $var 从 0 位置开始截 1 个字符
if [ ! -x "$var" ] ; then # -x 检测该绝对路径是否存在
return 1
fi
elif ! in_path "$var" "$PATH" ; then
return 2
fi
fi
}

if [ $# -ne 1 ] ; then # $# 传递给脚本或函数的个数 -ne 不等于
echo "Usage: $0 command" >&2 # $0 当前脚本名 >&2 重定向到标准错误
exit 1
fi

checkForCmdInPath "$1"
case $? in # $? 最后返回值,无误缺省返回 0
0 ) echo "$1 found in PATH" ;;
1 ) echo "$1 not found or not executaable" ;;
2 ) echo "$1 not found in PATH" ;;
esac

exit 0

参考拓展

1 《shell脚本实战(第2版》
2 Shell中的IFS解惑
3 Shell 中的中括号用法总结
4 shell脚本中的”2< “ “>&2” “&>”
5 shell 中三种字符串切分方法