第一章:The Missing Code Library--1.在系統路徑PATH中尋找程序

  每一個章節中的腳本獨立成文。 python

  代碼已測試過,Bash版本:GNU bash, version 3.00.15(1)-release (i686-asianux-linux-gnu) linux

  使用環境變量的Shell腳本,有一個隱藏的危險:它們可能部分正確的指向不存在的程序。好比你決定使用環境變量PAGER來靈活的演示腳本輸出,而不是經過編寫一個特殊的工具,那麼如何肯定PAGER這個值已經設置正確了呢?畢竟它不是一個有效的程序,你的腳本可能會崩潰。 正則表達式

  下面的這個腳本代表了在系統路徑中,如何經過測試來肯定一個給定的程序可否查找獲得。同時,它也很好的演示了一系列不一樣的腳本技術,包括腳本函數和變量切片(slicing)。 shell

第一個腳本
inpath.sh ---- 在系統路徑PATH中尋找程序 bash

inpath.sh

#!/bin/sh

in_path()
{
    # 給定一個命令和路徑,嘗試找到命令。
    # 若是找到了,而且可執行,返回0,不然返回1.
    # 注意,它暫時性的修改了IFS(輸入域分隔符),但完成後會重置。
    
    cmd=$1    path=$2    retval=1
    oldIFS=$IFS    IFS=":"         # 設置域分隔符

    for directory in $path
    do 
        if [ -x $directory/$cmd ]; then
            retval=0            # 執行到這步,代表在PATH中找到了程序
        fi
    done
    IFS=$oldIFS                 # 還原域分隔符
    return $retval
}

checkForCmdInPath()
{
    var=$1

    # 提示用法:
    # ${var#expr},從var開頭刪除最短匹配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
}
測試inpath.sh:向驗證程序傳遞一個初始參數,而後驗證返回碼。下面的代碼直接添加在inpath.sh中。

inpath.sh
 if [ $# -ne 1 ]; then
     echo "Usage: $0 commmand" >&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

測試的3種狀況:
1.程序存在: 函數

inpath.sh python

輸出:python found in PATH 工具

2.程序存在,但不在PATH上: 測試

inpath.sh test.sh

輸出:test.sh not found in PATH spa

3.程序不存在,但該程序有一個完整的包含路徑的名字: code

inpath.sh /usr/bin/python4

輸出:/usr/bin/python4 not found or not executable

其中,python你們都知道的,test.sh是一個可執行文件,python4估計這幾年都不會有的,哈哈。

分析下上面的腳本
   上面代碼中最不經常使用的地方可能就是:

${var%${var#?}}

   它是POSIX的變量切片方法。它有2個嵌套,內部嵌套 ${var#?},取得除變量var第一個字母外的剩餘內容,其中?是一個正則表達式,表示通配一個字符。外層 ${var%pattern},生成一個除去右匹配pattern後的剩餘子串。在此例中,剩下的就是字符串的第一個字母。
   check-ForCmdInPath能夠區分是一個程序仍是一個包含有路徑的文件名。方法是判斷第一個字母是否是斜線「/」。
   若是上面的切片方法使用起來有難度的話,能夠使用另外一種Bash和Ksh支持的方法,子串函數

${varname:start:size}

   好比,${varname:1:1}就是產生一個只有第一個字母的子串。注意,Shell中的這種用法,字符串下標是從1開始的。固然了,若是這2種技術你都不愛用的話,可是又想只取第一個字母,能夠用cut命令:

$(echo $var | cut -c1)
相關文章
相關標籤/搜索