文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>查询程序是否存在PATH中

查询程序是否存在PATH中

时间:2008-08-26  来源:yk325

使用环境变量的shell脚本(如MAILER和PAGER)存在一些隐藏的危险,可能有部份设置是指向不存在的程序。举个例子说下,在显示脚本的 输出时,如果我们选择灵活性强的PAGER设置来取代一个制式的特定工具,那么要如何确保PAGER值是指向一个存在的程序呢?而如果它是指向一个不存在 的程序,那么脚本将会中断。下面这个脚本会帮我们判断程序是否存在于PATH中,同时它也可以作为一个在不同工作环境中使用脚本技术(包含方程式与变数) 的良好范例。

脚本源代码

#!/bin/sh
# inpath - 证实我们所提供的程序是否能够执行
#   或存在于系统的设定的PATH中

in_path()
{
  # 给出一个路径及命令,脚本尝试去查询这个命令
  # 如果在PATH中找到并且可以执行,则返回0,否则返回1
  # 它将暂时修改IFS的值,执行后即恢复IFS的值.

  cmd=$1

  path=$2

  retval=1
  oldIFS=$IFS

  IFS=":"

  for directory in $path
  do
    if [ -x $directory/$cmd ] ; then
      retval=0      # 在指定的目录($directory)中找到指令($cmd),返回0
    fi
  done
  IFS=$oldIFS
  return $retval
}

checkForCmdInPath()
{
  var=$1

  # 下面的变量运作需要作下说明:${var#expr}会留下变量中expr后的一个字元,
  # 而${var%expr}则留下var变量中与expr不同的字串,下面的例子中,恰巧会留下第一个字元
  # 在Bash的环境下我们也可以使用${var:0:1}或cut -c1

  if [ "$var" != "" ] ; then
    if [ "${var%${var#?}}" = "/" ] ; then
      if [ ! -x $var ] ; then
        return 1
      fi
    elif ! in_path $var $PATH ; then
      return 2
    fi
  fi
}


*************************************************************
注意:我编写的脚本要存放到哪里去?
我 建议你在主目录(home目录)下新增一个名为"scripts"的新目录,并将其完整的路径加在PATH的变量中。我们可以通过echo $PATH指令来查看正确的PATH。要修改来修改PATH变量的话,使用vi工具去编辑你的主目录下的".login"或".profile"文档,, 以符合我们的需求。
**************************************************************


运行脚本
在执行这个脚本程序之前,我们必须在这段代码后再附加上一段,让它能够对前面执行的传回值进行判断,代码如下:

if [ $# -ne 1 ] ; then
 echo "Usage: $0 command" >&2 ; exit 1
fi

checkForCmdInPath "$1"
case $? in
  0 ) echo "$1 found in PATH"                  ;;
  1 ) echo "$1 not found or not executable"    ;;
  2 ) echo "$1 not found in PATH"              ;;
esac

exit 0

把上面的代码添加到原先的脚本代码后,我们就完成该脚本,可以运行并显示结果啦。如果你觉得这段新加上去的代码会很难理解,可以考虑将它去掉或者将其注释掉。

结果

我们分別准备三个档案来测试inpath程序:第一个是存在的档案、第二个也是存在的档案,但它的路径并不在PATH的设定中,第三个档案我们会输入完整的路径与档案名,但它并不存在。

$ inpath echo
echo found in PATH
$ inpath MrEcho
MrEcho not found in PATH
$ inpath /usr/bin/MrEcho
/usr/bin/MrEcho not found or not executable

改进与加强
${str#substr} 从str左边截掉第一个匹配到的substr,并返回剩下的字符串
${str##substr} 从str左边截掉最后一个匹配到的substr,并返回剩下的字符串
${str%substr} 从str右边截掉第一个匹配到的substr,并返回剩下的字符串
${str%%substr} 从str右边截掉最后一个匹配到的substr,并返回剩下的字符串
或 许这个程序较特別的部份是利用POSIX的变量分配方式:${var%${var#?}}。我们来探讨这个表达式,其实它是个表面复杂,但实际上却是两个 巢状的字串。在巢状字串里层的是${var#?},用来分离var变量第一个字元后的字串(? 是一个万用字元,代表着任何一个字元)。接着外层的 ${vat%pattern} 将移除与pattern(即里层运算后的结果)相符的字串,再产生一个字串。从我们这个脚本来看,产生出来的字串将是第一个字元。

这是相 当复杂的解释。但关键就在 check- ForCmdInPath 的运作。由于变量可能是单独的档案名(echo)或是完整的路径与档案名(如 "/bin/echo"),check- ForCmdInPath必须分辨出两者之间的不同,它会去检查这个变数的第一个字元是否"/",因此我们必须先将变数的第一个字元分离出来。

如 果POSIX的变数让你觉得恐慌,bash与ksh支支持另一种变量方法:${varname:start:size},这个方式可以直接从变量 varname中的第"start"个字元取得"size"个字元。举例来说${varname : 0 : 1},将会从varname变量中的第1个字元开始,共取得1个字元。当然,如果还是不喜欢这种取字元的方法,也可以考虑另一种方法:$(echo $var | cut -c1)。
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载