Linux shell| 學(xué)習(xí)記錄

來自:linux程序設(shè)計中文第四版

變量

變量引用

shell中,變量不需要提前聲明,默認(rèn)所有變量均被看做為字符串來存儲
引用變量名只需要在變量名添加 $符號

    variable=hello
    echo $variable 
    hello
    
    variable=”hello world ”  

注意:

  • 如果字符串里面包含空格,必須用引號括起來,另外等號兩邊不能有空格!
  • 雙引號與單引號的差別,雙引號會發(fā)生變量替換,單引號則不會替換
  • 被雙引號包括起來的變量,變量替換不會被阻止的,所以被稱為弱引用
  • 被單引號包括起來的變量,變量替換就會完全禁止,因此被稱為全(強(qiáng))引用
    ”$variable” 會被替換為變量表達(dá)式
    ‘$variable’  不會替換為變量表達(dá)式 

參數(shù)變量

  • $$ shell 本身的PID
  • $! shell 最后運(yùn)行的后臺Process 的PID
  • $? 最后運(yùn)行命令的結(jié)束代碼(返回值)
  • $- 使用set命令設(shè)定的Flag一覽
  • $* 所有參數(shù)列表
  • $@ $*的一種變體
  • $# 添加到shell的參數(shù)個數(shù)
  • $0 shell 本身的文件名
  • $1-$n 添加到shell的各種參數(shù)值,$1是第一個參數(shù)。。。。。。。

read命令: 用來讀取一個變量

read variable
Hello
echo $variable
Hello

變量運(yùn)算符

條件&測試

test 、[]命令

eg:
    if test  -f  hello.c   (; then)
    then    
    …
    fi
或者
    if [ -f hello.c ]
    then 
    …
    fi 

test 命令比較主要分三種類型,字符串比較,數(shù)值比較,文件相關(guān)比較

  • 字符串比較
    • string1 = string2 如果兩個字符串相同為真
    • string1 != string2 ….不同…..
    • -n string 如果字符串不為空則結(jié)果為真
    • -z string 如果字符串為null 則結(jié)果為真
  • 算術(shù)比較
    • expression1 –eq expression2 如果兩個表達(dá)式相等則結(jié)果為真
    • expression1 –ne expression2 不等
    • expression1 –gt expression2 如果expression1 大于 expression2 為真
    • expression1 –ge expression2 大于等于
    • expression1 -lt expression2 小于
    • expression1 -le expression2 小于等于
    • ! expression 如果表達(dá)式為假則結(jié)果為真
  • 文件測試
    • -d file 文件是一個目錄為真
    • -e file 文件存在則為真,歷史上,-e選項不可移植,通常使用的是-f選項
    • -f file 文件是一個普通文件則為真
    • -g file 文件得set-group-id位被設(shè)置則結(jié)果為真
    • -r file 文件可讀則結(jié)果為真
    • -s file 文件大小不為0 為真
    • -u file 文件的set-user-id 位被設(shè)置則結(jié)果為真
    • -w file 文件可寫則為真
    • -x file 文件可執(zhí)行則結(jié)果為真

控制結(jié)構(gòu)

if語句

    if   condition
    then
        statements
    elif     condition1
        statements
    else
        statements
    fi
for 語句
for variable in  values
do 
    statements
done

有用的變量 $(commands) for 命令的參數(shù)表來自括在$()中的命令的輸出結(jié)果

eg:
#!/bin/bash
for file in $(ls f*.sh); do
lpr $file
done 
exit 0

while語句

    while condition do
        statements
    done
eg:
    echo “please input passwd ”
    read trythis
    while [ “trythis !” = “passwd” ] ; do
        echo “sorry ,try again !!”
        read trythis 
    done
    exit 0

until 語句

與while相似,只是把條件測試反過來了,循環(huán)將反復(fù)執(zhí)行直到條件為真,而不是在條件為真時反復(fù)執(zhí)行。
    until condition
    do
        statements
    done
eg:
#!/bin/bash
until who | grep “$1” >/dev/null
do 
    sleep 60
done
#now ring the bell and announce the expected user.
echo –e ‘\a’
echo “****$1 has just logged in ****”
exit 0

case 語句

    case  variable  in
    pattern  [ | pattern ] …) statemetns ;;
    pattern  [ | pattern ] …) statemetns ;;
   esac
****************************************************            
    #!/bin/sh
    echo “Is it morning ? Please answer yes or no “
    read timeofday
    case “$tineofday” in 
    yes) echo “Good Morning”;;
    no)  echo  “Good Afternoon”;;
    y )  echo   “Good Morning “;;
    n   )  echo    “Good Afternoon” ;;
    *  )  echo “Sorry ,answer not recognized ” ;;
    esac 
****************************************************            
    #!/bin/sh
    echo “Is it morning ? Please answer yes or no “
    read timeofday
    case “$tineofday” in 
    yes|y|YES|Y) echo “Good Morning”;;
    no|n|NO|N)  echo  “Good Afternoon”;;
    *  )  echo “Sorry ,answer not recognized ” ;;
    esac 
            exit 0
****************************************************            
    #!/bin/sh
    echo “Is it morning ? Please answer yes or no “
    read timeofday
    case “$tineofday” in 
    yes|y|YES|Y) echo “Good Morning”
                    echo “up bright and early this morning”
                        ;;
    no|n|NO|N)  echo  “Good Afternoon”
                    ; ;
    *  )  echo “Sorry ,answer not recognized ”
          echo “Please answer yes or no ”
            exit 1      ; ;

    esac

命令列表

  • AND 列表
    從左邊開始順序執(zhí)行每條命令,如果一條命令返回的是true,右邊的下一條命令才能夠執(zhí)行。
         statement1 && statement2 && statements3 && …
    eg:
        #!/bin/bash
        touch file_one 
rm  -f file_two
if [ -f file_one ] && echo “hello” && [-f file_two ] && echo “there”
then 
    echo “in if”
else 
    echo “in else”
fi
exit 0
  • OR 列表
    statement1 || statement2 || statement3 || …
    從左邊開始順序執(zhí)行,如果一調(diào)命令返回的是false,它右邊的下一條命令才能夠被執(zhí)行,如此持續(xù)直到有一條命令返回true,或者所有的命令執(zhí)行完畢。
eg:
#!/bin/bash
rm –f file_one 
if [ -f file_one ] || echo “hello” ||echo “there”
then 
    echo “in if”
else 
    echo “in else”
fi 
exit 0

語句塊

如果想在某些只允許使用單個語句的地方使用多條語句,可以使用花括號來構(gòu)造一個語句塊。
    eg:
        get-confirm && {
                            grep –v “$cdcattnum” $tracks_file > $temp_file }

函數(shù)

    function_name () {
        statements 
    }
所有的函數(shù)定義需要放在函數(shù)調(diào)用之前
eg:
        #!/bin/bash
        foo() {
                echo “fuction foo is executing”
        }
        echo “script starting “
        foo
        echo “scripts ended”
        exit 0 

當(dāng)一個函數(shù)被調(diào)用時,腳本程序的位置參數(shù)$*,$@,$#等會替換為函數(shù)的參數(shù),可以用此方法來讀取傳遞給函數(shù)的參數(shù)。
可以用local 關(guān)鍵字在shell函數(shù)中聲明局部變量,此變量只在函數(shù)的作用范圍內(nèi)有效,如果一個局部變量和一個全局變量的名字相同,前者會覆蓋后者。

eg:
    #!/bin/bash
    sample_text=”gloabel_variable” 
    foo() {
            local sample_text=”local variable “
            echo  “Funcition foo is executing “
            echo $sample_text
        }

    echo “script  starting “
    echo $sample_text
    foo
    echo     “script ended”
    echo $sample_text
    

    # !/bin/bash 
    yes_or_no() {
            echo “Is  your name $*  ? ”
            while true 
            do 
                echo –n “Enter yes or no :”
                read x 
                case “$x in
              y|yes ) return 0;;
                n|no) return 1 ;;
                * ] echo “Answer yes or no “
                esac 
            done 
            }

下面是主程序

        echo “Original parameters are $* ”
        if yes_or_no  “$1”
        then 
            echo “Hi $1,nice name “
        else 
            echo  “never mind”
        fi 
        exit 0

命令

break命令

用來跳出for,while或者until循環(huán),可以為break提供一個數(shù)值參數(shù)來表示需要跳出的循環(huán)層數(shù),但是會大大降低程序的可讀性。

#!/bin/sh
rm –rf fred*
echo > fred1
echo >fred2
mkdir fred3
echo >fred4
for file in fred*
do 
    if [ -d “$file” ]; then 
        break;
    fi 
done 
echo first directory starting fred was $file
rm –rf fred*
exit 0

: 命令

冒號: 是一個空命令,偶爾被用于簡化條件邏輯,相當(dāng)于true的一個別名

    #!/bin/bash
    rm –f fred 
    if [-f fred ] ;then
    :
    else 
    echo file fred did not exist
fi
exit 0

continue 命令

類似C語言的continue,進(jìn)入下一次循環(huán)繼續(xù)進(jìn)行

    #!/bin/bash
    rm –rf fred*
    echo > fred1
    echo >fred2
    mkdir   fred3
    echo > fred4
    for file in fred*
    do 
        if [ -d “$file” ] ; then
            echo “skipping directory $file”
            continue 
        fi

continue 可以帶一個可選的參數(shù)用來表示希望繼續(xù)執(zhí)行的循環(huán)嵌套層數(shù),也就是說你可以部分的跳出嵌套循環(huán)

eg :
        for x in 1 2 3
        do
        echo before $x
        continue 1 
        echo after $x
        done

.命令與source命令

點(diǎn)命令用于在當(dāng)前shell中執(zhí)行命令;
. ./sehll_scrips
與source ,命令相似,用于在當(dāng)前shell 環(huán)境中執(zhí)行腳本
source命令能夠使子shell中的操作改變父shell中的環(huán)境變量,如果直接運(yùn)行則不能改變父shell中的環(huán)境變量
載入環(huán)境變量

echo 命令

    echo –n “string to output ”
    echo –e  ‘\a’

eval命令 很有用????

允許對參數(shù)進(jìn)行求值,

        foo =10
        x=foo
        y=’$’$X
        echo $y
                輸出為$foo
        foo=10
        x=foo
        eval  y=’$’$x
        echo $y
                輸出為10
        so,eval命令像一個額外的$,給出一個變量的值的值

exec命令

exec有兩種不同的用法,典型用法是將當(dāng)前shell替換為一個不同的程序

  • exec wall “Thanks for all the fiwsh”

腳本程序中會用wall替換當(dāng)前的shell程序,exec命令后的代碼都不會執(zhí)行,因?yàn)閳?zhí)行這個腳本的shell已經(jīng)不存在了
exec的各種方法是修改當(dāng)前文件描述符
exec 3 <afile 這種用法很少見。

exit n命令

exit命令使用腳本程序以退出碼結(jié)束運(yùn)行
#!/bin/bash
[ -f .profile ] && exit 0 || exit 1

export 命令

此命令將作為它參數(shù)的變量導(dǎo)出到子shell中,并使之在子shell中有效。默認(rèn)情況下, 在一個shell中被創(chuàng)建的變量在這個shell調(diào)用的下級shell中是不可用的,export 命令把自己的參數(shù)創(chuàng)建為一個環(huán)境變量,而這個環(huán)境變量可以被當(dāng)前調(diào)用的其他腳本和程序看見。

expr命令

expr命令將它的參數(shù)當(dāng)做一個表達(dá)式來求值,它的最常見的用法就是進(jìn)行如下形式的簡單數(shù)學(xué)運(yùn)算:
x=‘expr $x =1’

printf命令

和 c語言中的使用方法相似,但是不支持浮點(diǎn)數(shù),因?yàn)閟hell中所有的算術(shù)運(yùn)算都是按照整數(shù)來進(jìn)行計算的。

return命令

這個命令的作用是是函數(shù)返回,可以有一個數(shù)值參數(shù)作為函數(shù)的返回值。

set命令

set命令的作用是為shell設(shè)置參數(shù)變量
    eg:
        得到月份
        #!/bin/bash
        echo the date is $(date)
        set $(date)
        echo The month si $2
        exit 0

shift 命令

此命令將所有的參數(shù)變量左移一個位置,使$2變成$1,以此類推,原來$1的值將被丟棄,而$0的值將保持不變,如果shift命令時指定了一個數(shù)值參數(shù),則表示所有的參數(shù)將左移一定的次數(shù)。
eg:
            #!/bin/bash
            while [ “$1” !=” “ ];do
                echo “$1”
                shift
            done
            exit 0 

trap命令

trap命令用于指定在接收到信號后將要采取的行動。
trap command signal
HUP(1) 掛起,通常因終端或用戶退出而引發(fā)
INT(2) 中斷。。。。。。。。。
more man 7 signal
eg:
#!/bin/bash
trap ‘rm –f /tmp/tmp_file_$$
date > /tmp/tmp_file_$$
echo “please interupt (CTRL-C) to interrupt
while
……………..懶得敲了 linux程序設(shè)計中文第四版,page51

unset 命令

其作用是從環(huán)境中刪除變量或函數(shù),不能刪除shell本身定義的只讀變量(如IFS)
#!/bin/bash 
foo =”Hello World”
echo $foo
unset foo
echo $foo

find和grep命令

find / -name test –print 
從根目錄開始查找test的文件,輸出文件的完整路徑
find  / - mount –name test –print
這次不會搜索掛載的其他文件系統(tǒng)
還有好多,這里就不贅述了
grep命令使用正則表達(dá)式
    -I 忽略大小寫
    -c 輸出匹配行的數(shù)目,不輸出匹配行
    -l 只列出包含匹配行的文件名,不輸出真正的匹配行
    -v  對匹配模式取反,搜索不匹配行
    等等

export命令

    用于導(dǎo)出環(huán)境變量
    /etc/profile 
    /etc/bashrc
    $HOME/.bash_profile
    $HOME/.bashrc
    $HOME/.bash_logout
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容