shell編程基礎

1、人類如何與計算機"溝通"?

    翻譯官:編譯器、解釋器;

    編程語言:機器語言、彙編語言、高級語言

    

    靜態語言:編譯型語言

            強類型語言:變量在使用之前,需要聲明定義,甚至需要初始化

                        事先轉換成可執行格式

                        C、C++、Java、C#

    動態語言:解釋型語言

            弱類型語言:變量在使用之前,不需要聲明定義

                        邊解釋、邊執行

                        PHP、JSP、Perl、shell編程、Python


    面向過程:shell、C

    面向對象:C++、JAVA、Python、Perl


    變量:就是命名的內存空間;

    內存:就是編址的存儲單元;




    爲什麼會有變量:想象一下,如果沒有變量這個概念的話,讓計算機做一個1到10000的加法,這需要10000個內存空間去存放,但如果引入了變量這個概念,則需要兩個變量即可。


    變量類型的作用及功能:事先確定變量的存儲格式及長度

        整型,8bit: 256

        0-255, 溢出



                        字符變量

                        數值變量:

                            整型

                            浮點型:11.23,1.123*10,0.1123*10^2

                        eg:字符型:2014/9/30 64bit

                            數值型:99999    24bit        

                            布爾型:真、假

                            

                            字符:10:16bit

                            數值:10: 1010, 8bit

           

shell編程:shell弱類型的編程語言

       

什麼是強?什麼是弱?

        強類型:變量在使用前,需要聲明定義,甚至初始化

        弱類型:變量在使用時才聲明,甚至不區分類型

    

變量賦值:VER_NAME=VALUE


bash變量:

        本地變量(局部變量)

        環境變量

        位置變量

        特殊變量


本地變量:

set VARNAME=VALUE: 作用域爲整個bash進程;


局部變量:

local VARNAME=VALUE:作用域爲當前代碼段;


環境變量:

export VARNAME=VALUE;

VARNAME=VALUE

export VARNAME

        “導出”


位置變量:

$1,$2......


特殊變量:

$?(返回上一個命令的執行狀態碼),$*(參數列表),$@


程序的執行可以返回兩類結果:

     1、程序的執行結果;

     2、程序的執行狀態碼:0-255

            0:正確執行

          1-255:錯誤代碼


輸出重定向:

>:覆蓋輸出重定向

>>:追加輸出重定向

2>:錯誤覆蓋輸出重定向

2>>:錯誤追加重定向

&>:標準輸出+錯誤輸出重定向


撤銷變量:

unset VERNAME


查看變量:(環境變量+本地變量)

set


查看環境變量:

printenv

env

export 


腳本:命令的堆砌,按實際需要,結合控制流程機制實現的源程序


shebang:魔數

#!/bin/bash

#註釋,不執行


/dev/null:軟件設備 ; 位桶(bit bucket) 數據黑洞


腳本在執行時,會啓動一個子shell進程:

        在命令行運行的腳本,會繼承當前shell環境變量

        系統自動運行的腳本(非命令行啓動),則需要自我定義各個環境變量



        

練習:寫一個腳本,完成以下任務

1、添加5個用戶, user1,..., user5

2、每個用戶的密碼同用戶名,而且要求,添加密碼完成後不顯示passwd命令的執行結果信息;

3、每個用戶添加完成後,都要顯示用戶某某已經成功添加;

useradd user1

echo "user1" | passwd --stdin user1 &> /dev/null

echo "Add user1 successfully."

                             

條件判斷:

如果用戶不存在

添加用戶,給密碼並顯示添加成功;

否則

顯示如果已經沒在,沒有添加;


bash 中如何實現條件判斷:

    條件測試的類型:

                整數測試

                文件測試

                字符測試


    條件測試的表達式:

                [ expression ]

                ` expression `

                test expression


整數比較:

        -gt:大於

        -lt:小於

        -ge:大於等於

        -le:小於等於

        -eq:等於

        -ne:不等於


命令間的邏輯關係:

    &&:與,一假全假,當左邊爲假時,則不需要執行右邊,整個邏輯表達式即爲假

    ||:或,一真全真,當左邊爲真時,則不需要執行右邊,整個邏輯表達式即爲真


如果用戶user6不存在,就添加用戶user6

!id user6 && useradd user6

 id user6 || useradd user6


如果/etc/inittab文件的行數大於100,就顯示好大的文件;

[ wc -l /etc/inittab | cut -d " " -f 1 -gt 100 ] && echo "Large file"


變量命名規則:

1、只能包含字母,數字,下劃線,並且不能以數字開頭。

2、不能與系統中已有的環境變量重名

3、最好能夠做到見名知意


如果用戶存在,就顯示用戶已存在;否則,就添加此用戶;

id user && echo "user exists" || adduser user

!id user || echo "user exists" && adduser user


如果用戶不存在,就添加;否則,顯示其已經存在;

!id user && useradd user || echo "user exists"

 id user || useradd user && echo "user exists"


如果用戶不存在,添加並且給密碼;否則,顯示其已經存在;

!id user && useradd user && echo "user" | passwd --stdin user || echo "user exists"


練習,寫一個腳本,完成以下要求:

1、添加3個用戶user1, user2, user3;但要先判斷用戶是否存在,不存在而後再添加;

2、添加完成後,顯示一共添加了幾個用戶;當然,不能包括因爲事先存在而沒有添加的;

3、最後顯示當前系統上共有多少個用戶;

USERNUM1=`wc -l /etc/passwd | cut -d ' ' -f1`#用戶爲添加之前的事先存在的用戶數

id user1 && echo "user1 exists" || adduser user1

id user2 && echo "user2 exists" || adduser user2

id user3 && echo "user3 exists" || adduser user3

USERNUM2=`wc -l /etc/passwd | cut -d ' ' -f1`

echo "USERADDNUM=$[ $USERNUM2-&USERNUM1 ]"

echo "USERNUM2"


練習,寫一個腳本,完成以下要求:

給定一個用戶:

1、如果其UID爲0,就顯示此爲管理員;

2、否則,就顯示其爲普通用戶;


如果 UID爲0;那麼

  顯示爲管理員

否則

  顯示爲普通用戶

NAME=user16

USERID=`id -u $NAME`

if [ $USERID -eq 0 ]; then

  echo "Admin"

else

  echo "common user."

fi




NAME=user16

if [ `id -u $NAME` -eq 0 ]; then

  echo "Admin"

else

  echo "common user."

fi



if id $NAME; then

  


練習:寫一個腳本

判斷當前系統上是否有用戶的默認shell爲bash;

   如果有,就顯示有多少個這類用戶;否則,就顯示沒有這類用戶;

grep "bash$" /etc/passwd &> /dev/null

RETVAL=$?

if [ $RETVAL -eq 0 ]; then

   

if grep "bash$" /etc/passwd &> /dev/null; then

提示:“引用”一個命令的執行結果,要使用命令引用;

        比如: RESAULTS=`wc -l /etc/passwd | cut -d: -f1`;

       使用一個命令的執行狀態結果,要直接執行此命令,一定不能引用;

        比如: if id user1一句中的id命令就一定不能加引號;

 

      如果想把一個命令的執行結果賦值給某變量,要使用命令引用,比如USERID=`id -u user1`;

      如果想把一個命令的執行狀態結果保存下來,並作爲命令執行成功與否的判斷條件,則需要先執行此命令,而後引用其狀態結果,如

id -u user1

RETVAL=$?

此句絕對不可以寫爲RETVAL=`id -u user1`;

練習:寫一個腳本

判斷當前系統上是否有用戶的默認shell爲bash;

   如果有,就顯示其中一個的用戶名;否則,就顯示沒有這類用戶;


練習:寫一個腳本

給定一個文件,比如/etc/inittab

判斷這個文件中是否有空白行;

如果有,則顯示其空白行數;否則,顯示沒有空白行。

#!/bin/bash

A=`grep '^$' /etc/inittab | wc -l`

if [ $A -gt 0 ]; then

 echo "$A"

else

 echo "meiyoukongbaihang"

fi

        

 

#!/bin/bash

FILE=/etc/inittab

if [ ! -e $FILE ]; then

  echo "No $FILE."

  exit 8

fi


if grep "^$" $FILE &> /dev/null; then

  echo "Total blank lines: `grep "^$" $FILE | wc -l`."

else

  echo "No blank line."

fi


練習:寫一個腳本

給定一個用戶,判斷其UID與GID是否一樣

如果一樣,就顯示此用戶爲“good guy”;否則,就顯示此用戶爲“bad guy”。

#!/bin/bash

USERNAME=user1

USERID=`id -u $USERNAME`

GROUPID=`id -g $USERNAME`

if [ $USERID -eq $GROUPID ]; then

  echo "Good guy."

else

  echo "Bad guy."

fi


進一步要求:不使用id命令獲得其id號;


#!/bin/bash

#

USERNAME=user1

if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then

  echo "No such user: $USERNAME."

  exit 1

fi


USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`

GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`

if [ $USERID -eq $GROUPID ]; then

  echo "Good guy."

else

  echo "Bad guy."

fi




練習:寫一個腳本

給定一個用戶,獲取其密碼警告期限;

而後判斷用戶密碼使用期限是否已經小於警告期限;

提示:計算方法,最長使用期限減去已經使用的天數即爲剩餘使用期限;

如果小於,則顯示“Warning”;否則,就顯示“OK”。


圓整:丟棄小數點後的所有內容


#!/bin/bash

W=`grep "student" /etc/shadow | cut -d: -f6`

S=`date +%s`

T=`expr $S/86400`

L=`grep "^student" /etc/shadow | cut -d: -f5`

N=`grep "^student" /etc/shadow | cut -d: -f3`

SY=$[$L-$[$T-$N]]


if [ $SY -lt $W ]; then

  echo 'Warning'

else

  echo 'OK'

fi




練習:寫一個腳本

判定命令歷史中歷史命令的總條目是否大於1000;如果大於,則顯示“Some command will gone.”;否則顯示“OK”。



shell中如何進行算術運算:

A=3

B=6

1、let 算術運算表達式

let C=$A+$B

2、$[算術運算表達式]

C=$[$A+$B]

3、$((算術運算表達式))

C=$(($A+$B))

4、expr 算術運算表達式,表達式中各操作數及運算符之間要有空格,而且要使用命令引用

C=`expr $A + $B`



   

條件判斷,控制結構:


單分支if語句

if 判斷條件; then

  statement1

  statement2

  ...

fi


雙分支的if語句:

if 判斷條件; then

statement1

statement2

...

else

statement3

statement4

...

fi


多分支的if語句:

if 判斷條件1; then

  statement1

  ...

elif 判斷條件2; then

  statement2

  ...

elif 判斷條件3; then

  statement3

  ...

else

  statement4

  ...

fi




測試方法:

[ expression ]

` expression `

test expression


bash中常用的條件測試有三種:

整數測試:

-gt

-le

-ne

-eq

-ge

-lt


INT1=63

INT2=77

[ $INT1 -eq $INI2 ]

[[ $INT1 -eq $INT2 ]]

test $INT1 -eq $INT2  

文件測試:

-e FILE:測試文件是否存在

-f FILE: 測試文件是否爲普通文件

-d FILE: 測試指定路徑是否爲目錄

-r FILE: 測試當前用戶對指定文件是否有讀取權限;

-w

-x


[ -e /etc/inittab ]

[ -x /etc/rc.d/rc.sysinit ]


練習:寫一個腳本

給定一個文件:

如果是一個普通文件,就顯示之;

如果是一個目錄,亦顯示之;

否則,此爲無法識別之文件;




定義腳本退出狀態碼


exit: 退出腳本

exit #

如果腳本沒有明確定義退出狀態碼,那麼,最後執行的一條命令的退出碼即爲腳本的退出狀態碼;



測試腳本是否有語法錯誤:

bash -n 腳本


bash -x 腳本:單步執行




bash變量的類型:

本地變量(局部變量)

環境變量

位置變量: 

$1, $2, ...

shift

特殊變量:

$?

$#:參數的個數

$*: 參數列表

$@:參數列表

./filetest.sh /etc/fstab /etc/inittab

$1: /etc/fstab

$2: /etc/inittab


練習:寫一腳本

能接受一個參數(文件路徑)

判定:此參數如果是一個存在的文件,就顯示“OK.”;否則就顯示"No such file."


練習:寫一個腳本

給腳本傳遞兩個參數(整數);

顯示此兩者之和,之乘積;

#!/bin/bash

#

if [ $# -lt 2 ]; then

  echo "Usage: cacl.sh ARG1 ARG2"

  exit 8

fi


echo "The sum is: $[$1+$2]."

echo "The prod is: $[$1*$2]."


練習:寫一個腳本,完成以下任務

1、使用一個變量保存一個用戶名;

2、刪除此變量中的用戶,且一併刪除其家目錄;

3、顯示“用戶刪除完成”類的信息;




bash: 


引用變量:${VARNAME}, 括號有時可省略。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章