一、问题
判断一个文件是否是可执行文件,并且判断能否在系统PATH路径中找到。第一种情况:可执行且找到返回0,第二种情况没找到或者不可执行返回1,第三种情况可执行但没找到或没找到返回2。若有需求还可以细分。
二、解决
1、shell脚本
新建checkxfilepath.sh文件,chmod +x checkxfilepath.sh,然后执行。
####判断一个文件是否是 可执行文件,且判断能否在PATH中找到####
#!/bin/bash
CmdInPath() #判断是否在系统环境变量PATH中
{
cmd=$1 #$1为函数的参数1,filename
retval=1 #定义返回值变量
oldIFS=$IFS
IFS=: #设置新的IFS,并保存原来的以恢复使用
for directory in $PATH #扫描环境变量中的每个路径,IFS设置了环境中分隔符为冒号:(IFS通常是空格,制表符和换行符)
do
if [ -x $directory/$cmd ]; then #-x,判断文件有是否有可执行权限
retval=0
break
fi
done
IFS=$oldIFS #恢复原来IFS
return $retval
}
PathInPath() #判断是否在系统环境变量PATH中
{
retval=1 #定义返回值变量
oldIFS=$IFS
IFS=: #设置新的IFS,并保存原来的以恢复使用
for directory in $PATH #扫描环境变量中的每个路径,IFS设置了环境中分隔符为冒号:(IFS通常是空格,制表符和换行符)
do
if [ $directory = $1 ]; then
retval=0
break
fi
done
IFS=$oldIFS #恢复原来IFS
return $retval
}
checkForFileInPath()
{
var=$1
##对绝对路径的文件处理
##首先判断传入的非空串是否为绝对路径,即检测第一个字符是不是”/”,如果是,直接测–x##
if [ $var != "" ]; then #等价于:-n $var
if [ "${var%${var#?}}" = '/' ]; then #等价于$(echo $var | cut c1)取第一个字符
#等价于${var:0:1}
##此处为${}的匹配用法,${var%expression} ${var#expression},expression为正则表达式(?匹配单个字符)
#${var#?}返回var与任意字符匹配成功位置后的所有内容,即var第一个字符之后的所有
#${var%expression}返回var与expression匹配成功位置之前的所有内容,即var的第一个字符
##if条件若是表达式(需加方括号[]),if条件若是命令或函数,不需要方括号.shell中的true用0表示,if 0才执行then.
if [ ! -x $var ]; then
return 1 #not found or not executable
elif ! PathInPath ${var%/*}; then #比如var=/bin/ls,${var%/*}返回/bin
return 2 #not found in PATH
else
echo "executable:($var)" #find
return 0
fi
elif ! CmdInPath $var; then
return 2 #not found in PATH
fi
fi
}
###########代码执行起始位置###############
if [ $# -ne 1 ]
then
echo "Usage: $0 filepath"
exit 0
fi
##### 函数处理带路径和不带路径的####
#####返回1表没找到或不可执行,返回2表没找到,默认0表找到######
checkForFileInPath $1 #调用函数,并经第一个参数传给函数
case $? in #对函数返回的结果进行判断,$?:为函数的返回值
0) echo "found executable in path" ;;
1) echo "not found or not executable" ;;
2) echo "not found" ;;
*) echo "error";;
esac #case控制结构
2、执行
三、总结
(1)Shell函数的结构中没有形参,变量的定义和赋值不需要$符号而变量的引用需要,赋值两边要无间隙而条件两边要有间隙。(2)if条件若是表达式,需加方括号[];if条件若是命令或函数,不需要方括号。shell中的true用0表示,if 0才执行then;false用非0表示,执行elif或else后的语句。
(3)也可将CmdInPath()和PathInPath()综合到一个函数中,简化代码。