Linux shell篇---之一--shell基礎

一、shell基礎
1、shell的基本概念
shell就是系統跟計算機硬件交互時使用的中間介質,它只是系統的一個工具。
用戶界面shell(還有其他用戶界面如kde等圖形界面)-->內核--》硬件。

2、shell的種類
/bin/sh
/bin/bash  默認shell
/bin/ksh   兼容bash
/bin/tcsh  c shell
/bin/csh   已被tcsh替代,c shell
可以在/etc/shells文件中查看有哪些shell種類, 以下我們要學的都是bash這個shell的知識.


3、bash shell使用環境

1、登錄消息顯示數據      
(1)終端登錄顯示信息   /etc/issue
(2)所有用戶登錄顯示信息  /etc/motd
(3)環境文件設置:
/etc/sysconfig/i18n    //設置語言
/etc/profile           //設置幾個重要環境變量
/etc/bashre            //確定umask的功能


二、shell的基礎操作

1、TAB      指令和文件補全,連按兩次會把未寫完的指令或文件名都列出來。
2、alias  別名和unalias  取消別名

        我們可以通過alias把一個常用的並且很長的指令別名一個簡潔易記的指令。
        如果不想用了,還可以用unalias解除別名功能。
        直接敲alias會看到目前系統預設的alias

例: alias lm ='ls -al|more'    //以後就可以用lm命令代替這個命令了。

3、history 記錄命令歷史, 用向上鍵或向下鍵切換上一條命令或下一條命令。

4、通配符

*             //匹配文件中的任何字符串
?            //匹配單個字符串
[......]      //匹配方括號內的任何字符串   例: ls log[1-9] 顯示文件夾下log開頭以數字1到9結尾的所有文件,可能會顯示如:log1 log8  log4。
[!.....]      //取反操作,即匹配不是方括號內的任何字符串


5、常用符號


“”          //雙引號,可引用除字符$(美元符),  \(反斜槓),`(反引號)外的任意字符。且雙引號中的$號仍能代表變量。  \後面是普通字符表示換行,如\後面是特殊字符就表示轉義。
''            //單引號,裏面所有的內容全爲字符,包括$也變成字符,不再表示變量。
、、          //反引號,位於鍵盤的Tab鍵的上方。用於把系統命令輸出到變量。如: #shijin=The date is `date`,即把data這個系統命令執行的結果輸出給shijin變量。#echo $shijin 顯示結果爲 The date is 2011年 03月 14日 星期一 21:15:43 CST
\             //脫意符,即把後面的特殊字符轉換爲普通字符如\*,此時*就只是個星號,而不是代表任意字任的意思了。如果後面是普通字符,如123等普通字符就是換行。
#             //註釋
;            //連續命令分隔符
 
~             //用戶主目錄
&             //命令後臺執行

6、快捷鍵

ctrl+c        終止當前命令
ctrl+d        輸入結束
ctrl+s        暫停屏幕輸出
ctrl+Q        恢復屏幕輸出
ctrl+u        在提示符下刪除整行命令
ctrl+z        暫停當前命令

三、輸入輸出

(一)幾個命令

echo命令   //顯示文本行或變量。或把字符串輸入到文件
    例: #echo this is a monitor  //顯示一段文本。結果就是: #this is a monitor
        #echo $PATH   //顯示變量的值。

cat        //顯示文件內容,創建文件。
   例: #cat 1.txt   //顯示1.txt文件中的內容。
        #cat >1.txt  //建一個1.txt文件,並可以爲1.txt添加內容。按ctrl+c結束輸入。

read[-tp] 變量名        //從鍵盤或文件的某一行文本中讀入信息,並將讀到的值賦給一個變量。當有多個變量時,輸入的值將以空格分開按順序分別賦值不同的變量。

-p:後面會顯示提示的字符。
-t:等待輸入的秒數  

 例:#read var1 var2     //讀兩個值賦給變量 var1  var2,然後會出現輸入提示。
        this is             //var1的值爲this  var2的值爲is

read -p "please enter you user" user   //輸入此命令後會有輸入提示,輸入的內容將賦值給user變量。
如果此是用戶輸入了 Khp  ,那麼echo $user  的值會爲 khp

read命令一般用於人機交互,如可以要求用戶輸入帳號,密碼等,然後把這個變量用在腳本中引用等。



(二)重定向

1、系統設定三種默認傳輸:
代碼0  爲標準輸入  ,標準輸入設備一般爲鍵盤,鼠標,硬盤等。
代碼1  爲標準輸出, 標準輸出爲顯示器。
代碼2  標準錯誤輸出。

2、重定向輸出:
>     重定向輸出,覆蓋輸出,即如果輸出對象中已有內容,將被覆蓋。
>>    重定向輸出,但追加輸出,即把輸出的內容追加輸出對象已有內容的後面。
2>    重定向標準錯誤輸出。即只輸出錯誤的信息。覆蓋輸出。
2》   重定向標準錯誤輸出。即只輸出錯誤的信息。追加輸出。

     例:ls /root > 1.txt   //把root文件夾下的文件都重定向輸入到1.txt中。
         ls /root/1.tx 2>>1.txt  //因爲root目錄下沒有1.tx這個文件,就會顯示錯誤信息,會把錯誤信息存到1.txt文件中。
         ls /root/1.txt >>1.txt 2>>2.txt  //把命令執行的正確信息存放到1.txt下。把命令執行時的錯誤信息存到2.txt下。
         ls /root/1.txt >>1.txt 2>>1.txt  //可以把正確信息和錯誤信息放於同一個文件中。

&>   把命令執行的正確和錯誤信息存於同一個文件中。
例:ls /root/1.txt &>1.txt     ls /root/1.txt >>1.txt 2>>1.txt   這兩條命令執行結果一樣。

3、重定向輸入

<     重定向輸入
<<    重定向輸入 分界符   //從標準輸入中讀取數據,直到遇到分界符的內容即退出輸入。

      例:#sort <1.txt   //把1.txt文件中的內容排序後顯示出來。
          #sort <1.txt>2.txt  //把1.txt中的內容排序後,輸出到2.txt中。

(三)管道

1、 |  把前一個命令的輸出,當後一個命令的輸入。

例: ls -al /etc |less      //把etc文件夾下的內容顯示出來,然後同less命令進行分頁顯示。    


2、tee 雙向重定向。 從標準輸入讀取數據,並把輸出的內容同時顯示到標準輸出屏幕上,並且也同時存於別一個地方。
-a 即是追加到文件中,不加就是覆蓋。

  例: ls /etc |tee -a 1.txt   //把ls命令的執行結果輸出到屏幕的同時,存一份到1.txt中,且是追加方式, 不覆蓋1.txt中的原有數據。



四、命令執行順序

1、&&

command1 && command2   //當命令1執行成功後,才能執行命令2.前面的command1執行不成功,後面的command2不執行。

2、||

command1 || command2  //當command1命令執行不成功,就執行command2命令。command1命令執行成功的話,就不執行command2。

3、()

(command1;command2;command3;......)  //加上括號的組合命令,將按順序執行命令。

4、{}
{command1;command2;command3;.....}  //每一個命令單獨在一個子shell中獨立執行,而不是作爲一個整體依次執行。


五、字符操作(合併、切割)
1、cut
且來從標準輸入或文件文件中剪切抽取字符或域(即字段,一般是用TAB鍵把一段文本分爲多段)。以行爲單位。如果有很多行,將把所有行的都剪切下來。

cut [-cfd] file1 file2

-c 指定剪切的字符數
例:khp kuanghuaping  male
    sj sujun          female

 存於test.txt中。
例:
cut -c 4,6-7 test.txt  //剪切test.txt中所有行第4和6到7個字符,空格也算字符。所以此處會顯示:  
 ua //第一行的第4個是空格
suj

-f 剪切的域數,即段數。一般用TAB鍵把一段文本分爲多段。

cut -f 3 test.txt    //這裏剪切第3段,即  
male
female

注意:有些不支持空格作爲分段。只支持TAB分段。

-d 一般和-f一起使用,即指定用什麼字符來分隔文本成段,默認是空格或TAB,也可以手工指定。

 echo $PATH |cut -d : -f 3  //用冒號作爲文本的分段符,剪切第三段文本。

cut -d" " -f 1 test1.txt   //以空格作爲分段符。


2、paste
cut是從文件中抽取內容。paste也是從文件中抽取內容。類似於聯合兩個文件中的字段。
paste [-ds-] file1 file2
-d 手工指定文本的分隔符,不用默認的空格和tab.
-s 將每個文件合併成行,而不是按行粘貼。
-  使用標準輸入

例1:
test.txt內容:
khp kuanghuaping  male
sj sujun female

test1.txt內容:
hubi yc
hena zz

#paste test.txt test1.txt
顯示結果
#khp kuanghuaping  male hubi yc
 sj sujun female hena zz

例2:
paste -d: test.txt test1.txt   //兩個文件中的字段用冒號分隔。

khp kuanghuaping  male:hubi yc
 sj sujun female:hena zz

例3:
paste -s test.txt test1.txt  //同一個文本文件中的所有行都拼成一行顯示。

khp kuanghuaping  male  sj sujun female
hubi yc hena zz

例4:

ls/etc | paste -d" " ----    //etc目錄下的文件以空格爲分格符,分4列顯示出來。 有些不支持此選項。
類似於聯合了兩個文本。


3、join
連接兩個文件中的內容。類似於sql的連接,可以連接兩個文件中的相同部分,也可以連接不同部分。


join[option] file1  file2

 -a FILENUM:除了顯示匹配好的行另外將指定序號(1或2)文件中不匹配的行顯示出來
   -e EMPTY:將需要顯示但是文件中不存在的域用此選項指定的字符代替
   -i :忽略大小寫
   -j FIELD :等同於 -1 FIELD -2 FIELD,-j指定一個域作爲匹配字段
   -o FORMAT:以指定格式輸出
   -t CHAR :以指定字符作爲輸入輸出的分隔符
          join 默認以空白字符做分隔符(空格和\t),可以使用 join -t $'\t'來指定使用tab做分隔符
   -v FILENUM:與-a相似 但值顯示文件中沒匹配上的行
   -1 FIELD:以file1中FIELD字段進行匹配
   -2 FIELD:以file2中FIELD字段進行匹配

例1:
1.txt
khp kuanghuaping  male
sj    sujin      female
sc     lichen     male
sj     suko      female

2.txt
khp hubei  yc
sj  henan  zz
cw  beijin tz
(1)默認連接
join 1.txt 2.txt    //連接兩個文箇中域0相匹配的行進行連接,匹配的域0只顯示一次。
默認是以域0(即第1域)進行匹配,域0即第一個字段。連接並顯示匹配的字段。如果有多個相匹配的行,但匹配字段不是相鄰行時,只連接第一次出現的行。
khp kuanghuaping male hubie yc   
sj sujin female henan zz

而  sj suko female 此時當中隔了一行,就不做連接顯示,如果這兩行挨着,就會顯示。

(2)手工指定相同域段進行匹配連接
join -j 1 1.txt 2.txt   //手動指定域,以兩個文件的第1域作爲匹配域。和上面的結果一樣。

(3)手工指定不同域段進行匹配連接。

join -1 4 -2 3 1.txt 2.txt   //以第1個文件中的第4個域與第2個文件中的第3個域作爲匹配字段。

注:連接域字段相鄰且匹配時,兩行數據都會顯示出來。但如果匹配字段不相鄰,隔行後,只相連第一個匹配的行。剩下的即使匹配也不連接顯示。

(4)-a同時顯示不匹配的行。 -a1表示第一個文件,-a2表示第二個文件。
join -a1 a.txt b.txt
顯示如下:
khp kuanghuaping male hubie yc   
sj sujin female henan zz
sc     lichen     male    //第1個文件中不匹配的行也顯示出來在後面。
sj     suko      female

(5)-o 選擇性連接

join -o 1.1,2.2 1.txt 2.txt     //只顯示第一個文件中的第一列和第二個文件中的第二列。
即按默認匹配後,只顯示1.txt中的第1個字段,和第2個文件中的第2個字段,1.1,2.2中間用逗號分隔。
結果如下:

khp  hubie   
sj  henan


4、split

分拆文件,即把一個大的文件按大小,或按行數分割成多個文件。
split [-bl] file outfile  

-b:按大小分割,後面是指多少K大小。
-l:按行數,即多少行分割一個文件。如果省略-b  -l參數,將默認以1000行爲標準分割文件。

file:要分割的大文件的文件名
outfile:分割後的小文件的文件名前綴,不指定的話默認爲xaa  xab  xac排列下去。

例:

split -b 1024 bigone.txt   smfile  //把bigone.txt按每1024K大小分割成一個小文件,小文件名前綴以smfile開頭。


6、tr
刪除一個文件或標準輸入中的某個字符、字段,或對某個字符、字段進行替換。

tr[-d s c] [字符串1][字符串2] file1 file2 .....

-d:刪除某個字符。
-s:刪除所有重複出現字符序列,只保留第一個
-c:用字符串1中字符集的補集替換此字符集,要求字符集爲ASCII
字符範圍:

指定字符串1或字符串2的內容時,只能使用單字符或字符串範圍或列表。
[a-z] a-z內的字符組成的字符串。
[A-Z] A-Z內的字符組成的字符串。
[0-9] 數字串。
\octal 一個三位的八進制數,對應有效的ASCII字符。
[O*n] 表示字符O重複出現指定次數n。因此[O*2]匹配OO的字符串。
tr中特定控制字符的不同表達方式
速記符含義八進制方式
\a Ctrl-G  鈴聲\007
\b Ctrl-H  退格符\010
\f Ctrl-L  走行換頁\014
\n Ctrl-J  新行\012
\r Ctrl-M  回車\015
\t Ctrl-I  tab鍵\011
\v Ctrl-X  \030

\040      空格

例:

tr -s "[a-z]"result.txt //去除result.txt裏面的重複的小寫字符

tr -d '\0' <1.txt   //刪除1.txt中的所有空字符。'\0'可寫成"[\0]"

cat a.txt |tr "[a-z]" "[A-Z]" >b.txt  //把a.txt中的所有小寫字母轉換成大小的,並存到b.txt中。

tr -cs "[a-z][A-Z]" "[n]" <1.txt   //把1.txt中所有非字母的字符全刪除。即非 "[a-z][A-Z]"的字符全刪除,注意這兩個集合是在一個引號內的,沒有分開。

tr -s "[\r]" "[n]" <1.txt            //把1.txt中的所有tab鍵換成空格鍵。


7、sort


對文件進行排序
sort[-k u r m t b f c] file  [-o outfile]

-k:按哪個字段排序,默認按0域進行排序。
-u:就是uniq,重複的行僅顯示一行,但與uniq的區別在於,sort不管你相同的行相不相鄰,都算作重複行。
-r:反向排序
-t:設定不同的分隔符,默認是TAB
-b:忽略文件前面的空格部分。
-f:忽略大小寫差異
-c:測試文件是否已分類,分類則不返回信息,不分類則反回信息。
-o outfile:把排好序的文件存入到哪個文件,類似於重定向。
-n:指定爲數值類型,如1,2,3,4,5,6,7,8,9,10,11,如果不指定數值類型,那麼11會排到2的前面。

例:2.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4

sort -t: -k2 -n 2.txt  //以冒號作爲行的分段符,並以第二段的值來排序,且第二段的值是數值類型。
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3


8、uniq
刪除重複行或禁止重複行。uniq的重複行的標準是相鄰的重複行,要求沒有間隔的。有間隔的都不算重複行。這是與sort -u的區別。

uniq [-u d c f] file

-u:只顯示不重複的行。
-d:只顯示有重複數據行,每種重複只顯示一次。
-c:顯示每一重複行出現的次數。
-f:(或-n) 前n個域被忽略。

例:1.txt全文:
test
test
my
test
123
123
456


uniq 1.txt
結果:
test
my
test
123
456

uniq -u 1.txt
結果:
my
test
456

9、wc
計算文本的數據,如有多少行,多少字符。

wc[-l w m] file

-l:顯示有多少行
-w:顯示有多少字,如是英文則一個單詞表示一個字
-m:顯示多少字符,如是英文,每個字母就是一個字符。

10、find


11、xargs



六、正則表達式



(一)基本字符集及含義

1、^(6鍵上檔鍵):只匹配行首
2、.(點):只匹配單個字符,是任意單個字符。(除NUL)。
3、$:只匹配行尾。
4、*:能匹配前面的字符零次或任意次,是表示匹配次數的。例: zo* ,可以匹配zo,zoo,zoooo,z(即匹配前面的字符0次),等價於zo\{0,\},o字符至少出現一次。
      .* 組合,表示任意長度的任意字符。a.*b,即a開頭,b結尾的任意字符串。amnb  ab  aab都匹配。
5、[]:匹配括號內字符範圍。
6、\:去意符,即把特殊字符轉換爲普通字符。
7、pattern\{n,m\}:即pattern出現n到m次。例:  (AC)\ {3,5\}B,即A出現3到5次,即ACACACB,ACACACACACB都匹配。
8、pattern\{n\}:即pattern只出現n次。例: A\{3\}B,即AAAB。
9、pattern\{n,\}:即pattern至少出現n次。 例:A \{3,\}B    ,即AAAB,AAAAAAAAAB都匹配,只要A至少有3個即可。
10:\< 或\b :其後面的任意字符必須作爲單詞首部出現。例: grep "\<root" /etc/passwd 找單詞首部有root的行。grep "\broot" /etc/passwd一個意思。
11:\> 或\b:其前面的任意字符必須作爲單詞首部出現

grep "\<root\>" /etc/passwd   精確查找含有root單詞的行。
12、  \(\):分組。 \(acd\)  把acd當一個整體。 要重複也是acd一起重複。
---------
擴展的正則表達式字符及其意義,只能用在egrep中:
+:匹配前面的字符一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo"“zoooooo",但不能匹配 "z"。+ 等價於 zo\{1,\},即o至少匹配1次。
?:匹配前面的字符零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等價於 do(es)\{0,1\}。
():表示一個字符集合或用在expr中。
|:表示或,匹配一組可選的字符。
(二)grep和egrep

gerp [option]  '正則表達式' [文件]

option:選項
正則表達式:要搜索的字符
文件:指從哪個文件中搜索。

-a:在二進制文件中,以文本文件的方式搜索。
-c:只輸出匹配行計數,即搜索到匹配的次數。
-i:不區分大小寫
-n:顯示匹配的行號
-v:取反。顯示不匹配的文本的所有行。
-h:查詢多文件時,不顯示包含匹配字符的文件名。
-l:從多個文件中搜索時,只顯示包含匹配字符的文件名。
-s:不顯示不存在或無匹配文本的錯誤信息。






六、變量類型

1、本地變量

(1)作用域:整個腳本進程有效。只在當前用戶shell下有效,子shell下也是無效的。
        切換用戶,或同一用戶下的不同shell,或子shell下都無效。關閉shell就會消失。

(2)變量的定義,查看和撤消

定義一個變量:

     變量名=變量值
      例: name=khp  
      也可以: set name=khp   //只是大多數時候set省略了。

查看一個變量值:
echo $name   //查看變量name的值。也可以是echo ${name},花括號大多數情況下可以省略。


引用變量:

$變量名   或  ${變量名}

撤銷變量:

unset 變量名  //撤消一個變量。

查看所有變量:

set   用set命令查看所有的本地變量。



2、局部變量

作用域:只能當前代碼段有效,同一shell中的不同代碼段都不能引用。

local VARNAME=VALUE   //加關鍵字local,很少用。


3、環境變量

作用域:當前用戶shell和子shell下有效。就算同一用戶名,不同的shell下也無效。  用bash命令打開子shell

定義方法:
(1)export VARNAME=VALUE  //加關鍵字export

(2)VARNAME=VALUE         //定定義成本地變量。
     export VARNAME        //也可以先定義爲本地變量,然用後關鍵字export把本地變量轉換爲環境變量。

環境變量的幾個命令:
env :查看環境變量

export :查看哪些變量是由本地變量轉換爲環境變量的。

有導出功能。


4、位置變量

(1)普通位置變量

腳本中可以用位置變量。然後在執行腳本時,在腳本後面給這些位置變量賦值。位置腳本不能超過9個。
$0 $1 $2 $3 ......$9   //其中$0是腳本名。

例:
    #touch test.sh      
    #vim  test.sh
    
 腳本編號:
#!/bin/bash    //腳本中必須有的,指示腳本用哪個腳本程序執行,執行腳本程序的位置。
#test          //腳本描述

echo "這個腳本的名稱是:$0"
echo "這個腳本的第一個參數值是:$1"
echo "這個腳本的第二個參數值是:$2"

腳本執行:

#./test.sh  first second     //給腳本的位置變量賦值,用空格間格。

執行結果:

這個腳本的名稱是:test.sh
這個腳本的第一個參數值是:first
echo "這個腳本的第二個參數值是:second

(2)位移位置變量

shift[n]   //參數向左位移n位。

在腳本中每shift一次,參數向左位移一次。位移後,被位移的參數從參數表中刪除。

例: shift.sh
#!/bin/bash
#
echo this is $1
shift
echo this is $1
shift 2
echo this is $2


調用:
./shift.sh 1 2 3 4 5

結果:
this is 1     //第1個參數爲1
this is 2     //echo this is $1,如果沒使用shift,此時的$1應爲1,但shift是把所有參數向左位移了一位,且被位移的參數值直接從參數值列表中刪除了,即1已經不在參數值中了,只有2,3,4,5了,所以2變成了第1個參數的值了。
this is 5     //shift 2,即把參數值向左位移兩位,因現在參數值列表中只有2,3,4,5,所以位移兩位後,參數值列表就只有4,5了。此時第二個參數值爲5,所以此處顯示爲5.




5、特殊變量

$#    //返回腳本中腳本參數的個數。如把$#插入到腳本中,那麼執行時,此位置將顯示腳本中使用的參數的個數。

$?    //顯示上一個命令執行後的狀態。是狀態而不是結果。0表示執行結果沒有錯誤,其他任何值都表示有錯誤。可以作爲判斷條件來使用。

$$    //腳本運行的當前進程ID號。

$@   //與$#相當。

$-   //顯示shell使用的當前選項

$!   //後臺運行的最後一個進程的進程ID號。
 
$*   //以一個單字符串顯示所有向腳本傳遞的參數,與位置變量不同,此參數可超過9個。


七、條件比較和邏輯關係
1、整數比較
[ num1 比較條件 num2 ]   //中括號與數字間一定要有空格。
test 比較條件             //也可以比較

-eq  :數值相等,則爲真,不相等就爲假。
-ne  :兩數如不相等,則爲真。兩數相等爲假。
-gt  :大於則爲真,否則爲假。
-lt  :小於則爲真,否則爲假
-ge  :大於等於爲真,否則爲假
-le  :小於等於爲真,否則爲假

例:
 

#num1=120
#[ $num1 -eq 120 ]
#echo $?
#0

2、字符串比較
[ string1 比較運算符 string2 ]

=     兩字符串相同爲真。
!=   兩字符串不相同爲真
-z    空字符串爲真。
-n    非空串爲真
>     大於字符長度爲真
<     小於字符長度爲真

例:
#export num    //定義一個環境變量,但沒有賦值
# [ -z $num ]  //測試此環境變量是否爲空。空則爲真。
#echo $?       //結果爲0,表示爲真。
#0

3、文件狀態測試

[ 狀態符 文件名 ]

-d  文件是否是目錄,是就爲真。
-r  文件是否可讀,可讀爲真
-w  文件是否可寫,可寫爲真
-x  文件是否可執行,可執行爲真
-L  文件是否是符號鏈接,是爲真
-s  文件長充大於0,非空爲真。
-f  是否爲正規文件,正規爲真。
-u  文件有suid設置爲真。

例:
#[ -w 1.txt ]    //1.txt是否可寫,可寫即爲真。
#echo $?


4、邏輯關係

&&  邏輯與    -a
||  邏輯或    -o
!  邏輯非

例:

#! id khp &> /dev/null && useradd khp   //id命令查詢khp這個命令是否存在,如果存在,則爲真了,即有用戶名存在就爲真了,所以要在前面加上!,即用戶不存在才爲真,那麼執行與後面的添加用戶命令。

5、算術運算的辦法
A=6
B=9

let算術表達式      C=$A+$B    
$[算術表達式]      C=$[$A+$B]
$((算術表達式))   //雙小括號

6、expr用法

expr一般用於整數值,也可以用於字符串。是一個手工命令行計數器。

expr  元素 操作符  元素  //一般格式

(1)四則運算,即加減乘除的運算。

expr 10 + 10   //數字與加號之間要有空格
結果爲20

expr 10 % 3   //求餘
結果爲 1

(2)數值測試。可以用expr測試一個數,因爲當expr計算的是一個非整數時會返回錯誤。

 #rr=3.14
# expr $rr + 3
expr: 參數數目錯誤    //如參數中不是一個整數會報錯。所以可以用來測試一個參數的值是不是整數。
# rr=3
# expr $rr + 3
6

(3)增量計數

loop=0   //變量賦初值
loop=`expr $loop + 1`  //一定要加反引號,即表明反引號中的所有內容作爲一個命令的整體運行,expr 會作爲命令,  $loop 會作爲變量的引用, + 1會作爲算術運算。結果爲 1

c=`expr $A + $B`  //也是一種算術運算

下面講一下雙引號和單引號與反引號之間的區別。
雙引號的區別:
loop="expr $loop + 1"   //只會把$loop作爲變量引用,其他作爲字符。
echo $loop
expr 1 + 1

單引號:
loop=‘expr $loop + 1’    //單引號裏的所有內容作爲字符串。
echo $loop
expr $loop + 1


(4)模式匹配
#cc=myname.doc
#expr $cc : '.*'   //.(點)代表任意單個字符,*表示任何字符,即貪婪模式,匹配最多的字符。但這裏的變量中的字符串中不能有空格,否則會出錯,即如果 cc="my name.doc" ,則會出錯。
6
 



八、語句

1、if then else  語句

     if (條件1)
     
     then 命令1
   
       elif  條件2
       then  命令2
     
     else  命令3
     fi                     //用fi結尾

如果條件1爲真,則執行命令1,然後跳出if語句,如果條件1不成立,那麼判斷條件2是否爲真,如爲真則執行命令2,如不爲真,則執行命令3.



2、case   
 //如果變量值與模式1中的值匹配,那麼執行模式1中的命令。並不再與後面所有的模式進行匹配。如果模式1不匹配,則按次序與下面的模式條件進行匹配。即匹配一個後,後面的將不再進行匹配,跳出。

case 變量值   in


模式1)

     命令1
     命令2
     ......
     命令n
      ;;        //模式之間用兩個分號隔開
模式2)

     命令1
     命令2
     ......
     命令n
     ;;
esac


3、for循環

 //如果變量的值 在後面的列表值中,就執行下面的do。要多個循環,列表值就要加多個值。

for 變量名  in  列表值

do  

     命令1
     命令2
     ......
     命令n

done



4、until循環

//until循環至少執行一次,即先執行do後面的命令,執行完後再判斷條件,如果條件爲真,繼續執行do後面的語名,如果不爲真則跳出循環。


until 條件      
do
   
     命令1
     命令2
     ......
     命令n

done


5、while循環

//先判斷while後面的條件,如果條件爲真,繼續執行do後面的語名,如果不爲真則跳出循環。
while 條件      

do
   
     命令1
     命令2
     ......
     命令n

done


6、break 和contiune

break 跳出整個循環語句,即使多層嵌套也全部跳出。
contiune 跳出本次循環。接着執行下次循環。


九、函數

1、函數的定義

函數名()

 {
命令......
 }


2、函數文件的創建

與腳本文件格式一模一樣。一個函數文件中可以定義多個函數。


3、函數的調用:

(1)調用在腳本中的函數

用函數名即可調用。但函數的定義一定要函數調用之前。函數中可以使用參數。


(2)調用腳本外的獨立函數文件

在絕對路徑前加.(點)來調用獨立函數文件
在腳本的開始部分用絕對路徑把這個函數文件導入進來。 ./var/shell/adduser.sh
然後在腳本中就可以直接用函數文件中的函數名來調用函數了。一個函數文件可以定義多個函數。

(3)函授載入檢測
 ./var/shell/adduser.main
set

//在shell中載入函數文件名下面用set命令即可查看是否已載入。


(4)函數的刪除

unset命令刪除函數。
在定義好的函數下用unset 函數名
或在包含進的函數文件名下用unset命令,都可以刪除函數,即不使用函數,函數沒有真的沒刪除。


4、參數的傳遞

詳見位移變量。


5、函數的使用

1、`函數名`   :用反引號引起函數名,即表示函數的執行結果。可以把函數的執行結果賦值給變量。

十、腳本調試

sh[-nxv] 腳本名

-n:不執行腳本,僅查腳本的語法問題。
-x:將腳本的內容顯示到屏幕上,且將每一步的執行結果也顯示出來。
-v:執行腳本前先將腳本的的內容輛出到屏幕,到最後執行腳本,且將腳本的執行結果顯示出來。



十 一、sed

1、概述
(1)sed是一個非交互性文本流編輯器,它編輯文件或標準輸入導出文件的拷貝。注意只是拷貝,sed並不與原文件打交道,它只是操作原文件或標準輸入的一個拷貝,然後用命令改動,再重定向到一個文件或輸出到屏幕。
(2)sed 是一種在線編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲“模式空間”(pattern space),接着用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。接着處理下一行,這樣不斷重複,直到文件末尾。
(3)vi也是文本編輯器,但是是交互性的。

2、sed的幾種使用方式:


sed [option]  'AddressCommand'   files......

option:
  -e:直接在命令行上運行sed操作,並且可以運行多腳本。如: sed -e script -e script 。我們把一條完整的sed語句叫sed腳本。
  -n:靜默模式,不再默認顯示模式空間中的內容,只有經過sed處理的行才顯示出現。
  -f:執行sed腳本文件。 sed -f /home/khp/sed.script  即把sed命令一行一行的寫到了sed.script文件中了,然後用sed -f 命令去讀取這個腳本文件。
  -i:直接修改原文件,而不是修改拷貝。  
  -r:可以在sed命令中使擴展正則表達式。

Address:一般爲行號或模式
    x:x爲行號,如2,即第2行。
    x,y:行號範圍,如,2,8即第2到8行。
    /pattern/:模式匹配,包含pattern字符串的行。如,/disk/ 即所有包含 有disk字符串的行。
    /pattern1/pattern2/:同時包含pattern1和pattern2的行。要都包含。
    /pattern1/,/pattern2/:第一次匹配pattern1字符串的行,到第一次匹配pattern2的行之間的所有行。兩次匹配行之間的所有行。
    $:最後一行。
    x,+N:從第x開始,向後N行。5,+6,第5行開始向後的6行,全匹配。
    x,y!:不匹配x和y行的所有行。例,4,8!即4到8行外的所有行。


command:
  p:顯示,打印匹配行到屏幕。例: sed '1,$p' test.txt   顯示出test.txt中第一行到最後一行的所有內容。
  a:新增,在指定行後附加文本,會出現在當前行的下一行。
      a\string:將字符串添加到指定行後。   sed '5a\this is append' test.txt  把字符串this is append追加到第5行後面。
  i:插入,插入字符到定位行,但會在定位行的上一行出現。
  c:替換,c後面可接字符串,替換指定行或行與行之間的內容。
  d:刪除,刪除定位行。
  s:搜索,查找並替換,不僅可搜索,還能替換,一般與正規表達式一起使用。
      sed 's/khp/kuang/gi' /home/khp/test1  查找test1中包含khp的字符串,用kuang替換。g爲全文替換,不加的話,只替換每行中第一個匹配的字符串。i爲忽略大小寫。
      sed 's/khp/$boy/p' /home/khp/test1  查找到test1中的khp字符串,在前面加上字符串boy。
      sed 's/khp/boy$/p' /home/khp/test1  查找到test1中的khp字符串,在後面加上字符串boy。
  r:讀取,將指定文件的肉容添加到符合條件的行處,即從另一個文本中讀取內容添加到本文件中的匹配行後面。 sed '2,8r /home/khp/test1' /home/khp/test2  把test1中所有的內容添加到test2文件中第2到8行後面,2到8行每行後都添加一次。
  w:寫入,將地址指定的範圍內的內容另存至指定的文件中。 sed  -n '/khp/w /home/test2' /home/test1  把test1中含有khp字符的行添加到/home/test2中。
  =:顯示行號,sed -n '/^$/='  a.txt  顯示a.txt中的空白行號。



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