Linux超酷脚本-Finding Programs in the PATH
作用:验证一个指定的程序能否在当前系统里找到,这里可以是一个绝对路径的程序,或是一个相对路径的程序.
源程序如下:
#!/bin/bash
in_path(){ local cmd="$1"; local path="$2"; local retval=1 local oldIFS="${IFS}"; local IFS=":" for directory in $path do if [ -x $directory/$cmd ];then retval=0 fi done IFS=$oldIFS return $retval}
checkForCmdPath(){
local var=$1 if [ "${var%${var#?}}" = "/" ];then if [ ! -x "${var}" ];then return 1 fi elif ! in_path "${var}" "${PATH}";then return 2 fi}
if [ $# -ne 1 ];then echo "Usage: $0 command" >&2 ;exit 1fi
checkForCmdPath "$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
分析:
1)$#用于统计传递参数的个数,如果我们在程序后面加了三个参数,这里的$#将是3,如果没有指定参数,这里的$#将是0.2)关于函数的定义,我们有两种定义函数的方法,如下:checkForCmdPath(){}另一种方法:function checkForCmdPath{}两种函数的性质完全一样,但是如果采用第二种方法,大括号要和函数名有一个空格或回车键做分隔符,否则function关键字会把大括号和函数名连在一起当做函数名,像下面的定义是错误的:function checkForCmdPath{}
3)${var%${var#?}},这是一个截取字符串的操作,${var#?}取出$var变量第2个字符到最后一个字符,再通过${var%$strings}取出$var变量的第一个字符.首先我们分析${var#?},从左向右截取第一个string后的字符串如下:var="abcdefabcdef"echo ${var#?}bcdefabcdef这里的?号是指任意一个字符.如果是$(var#abc),截取后的结果是defabcdef如果是${var#def},截取后的结果是abcdefabcdef这说明一定要从左第一个字符进行完全配匹,如不能完全配匹则返回原字符串.
再下来分析$(var%strings),它表示从右向左截取第一个string后的字符串如下:var="abcdefabcdef"echo ${var%def}abcdefabcecho ${var%abc}abcdefabcdef上面的例子说明它从右第一个字符进行配匹,如不能完全配匹则返回原字符串.
最后我们看几个截取字符串的实例:echo ${var##*abc} //从左向右截取最后一个string后的字符串defecho ${var#*abc} //从左向右截取第一个string后的字符串 defabcdefecho ${var%%cde*} //从右向左截取最后一个string后的字符串abecho ${var%cde*} //从右向左截取第一个string后的字符串abcdefabecho ${var:1:4} //截取第1个字符到第4个字符,注意这里是从第0个字符算起bcdeecho ${var:1} //截取第1个字符到最后一个字符 bcdefabcdefecho ${var}|cut -c1,4 //截取第1个字符和第4个字符,注意这里是从第1个字符算起adecho ${var}|cut -c2-8 //截取第2个字符到第8个字符bcdefab
4)对于函数的返回值,要说明的是函数会将函数中最后一条语句中的返回值传给它的调用程序.它的值是0-255,如果出现负值或会用补码将负值转为正值,再在末尾加1进行处理,如果是大于255的值,会用这个值一直减256,直到最后一个值不足256为止,例如return 800,将得到值将是32,也就是800-256-256-256=32
5)对于本例中,我们用IFS来处理路径的问题,IFS变量用于定义分隔符,默认的IFS是$' \t\n',也就是空格或者tab,或者回车.
我们用下面的例子来说明IFS的用途,for record in `cat /etc/passwd`do echo $recorddone输出的结果可能是这样:gopher:x:13:30:gopher:/var/gopher:/sbin/nologinftp:x:14:50:FTPUser:/var/ftp:/sbin/nologinnobody:x:99:99:Nobody:/:/sbin/nologinrpm:x:37:37::/var/lib/rpm:/sbin/nologindbus:x:81:81:Systemmessagebus:/:/sbin/nologin
原passwd文件是这样:gopher:x:13:30:gopher:/var/gopher:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologinnobody:x:99:99:Nobody:/:/sbin/nologinrpm:x:37:37::/var/lib/rpm:/sbin/nologindbus:x:81:81:System message bus:/:/sbin/nologin
这说明默认的IFS同时用空格,TAB,回车来做分隔,gopher:x:13:30:gopher:/var/gopher:/sbin/nologin一行没有空格和TAB,所以用回车来分隔,得到了一条正确的记录,而ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin一行有空格,所以它用空格来分隔,这样得到了两条记录,我们将IFS改成用回车来分隔即可解决这个问题,如下:
oldIFS=$IFSIFS=$'\n'for record in `cat /etc/passwd`do echo $recorddoneIFS=$oldIFS
输出:gopher:x:13:30:gopher:/var/gopher:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologinnobody:x:99:99:Nobody:/:/sbin/nologin
来自: http://home.lupaworld.com/home-space-uid-56821-do-blog-id-233541.html