1. 程式人生 > 實用技巧 >Linux之shell 基本知識

Linux之shell 基本知識

一、shell環境定義

  • 臨時環境變數

臨時環境變數指的是使用者在當前環境變數生效的變數,使用者登陸系統後,直接在命令列定義的環境變數只能在當前的登陸環境中使用,當退出系統後,臨時環境變數則失效

  • 將環境變數永久生效

通過將環境變數定義寫入到配置檔案中,使用者每次登陸時系統自動定義,則無需再到命令列重新定義。

定義環境變數的常見配置檔案如下:

系統環境變數:/etc/profile 針對系統所有使用者生效

使用者環境變數:$HOME_name/.bash_profile 針對特定使用者生效。當用戶登陸系統後,首先繼承/etc/profile檔案中的定義,

再應用$HOME/.bash_profile檔案中的定義。

系統預定義的環境變數:如 $PATH、$HOME、$SHELL、$PWD等等,對所有使用者有效

二、shell指令碼程式設計

  • 建立shell指令碼

一個shell指令碼通常包含如下部分:

首行

第一行內容在指令碼的首行左側,表示指令碼將要呼叫的shell直譯器,內容如下:

#!/bin/bash

#! 符號能夠被核心識別是一個指令碼的開始,這一行必須位於指令碼的首行,/bin/bash是bash程式的絕對路徑,

在這裡表示後續的內容將通過bash程式解釋執行

建立指令碼的三種方式:

第一種:#echo "" >first.sh
第二種: #touch first.sh
第三種: #
vi firsh.sh

註釋:

帶#開頭的就是一段註釋

  • shell指令碼的許可權

一般情況下,預設建立的指令碼是沒有執行許可權的,需要自行修改許可權

修改許可權

  • shell指令碼的執行

1、輸入指令碼的絕對路徑或相對路徑

絕對路徑:/home/hyx/test.sh
相對路徑:./test.sh

2、bash或sh+指令碼

bash test.sh
sh test.sh

注意:當指令碼沒有x許可權時,root和檔案所有者可以通過該方式正常執行。

3、在指令碼的路徑前再加“.”,或source

source test1.sh
./test1.sh

區別:

第一種和第二種會新開一個bash,不同bash中的變數無法共享

第三種是在同一個shell裡面執行的

  • shell變數

變數的分類

Linux Shell中的變數分為使用者自定義變數、環境變數、位置引數變數和預定義變數

可以通過set參看系統中存在的變數

  • (1)使用者自定義變數

使用者自定義變數由字母或下劃線開頭,由字母,數字或下劃線序列組成,並且大小寫字母的意義不同,變數名

長度沒有限制

設定變數:習慣上用大寫字母來命名變數。變數名以字母表示的字元開頭,不能用數字。

變數的呼叫

在使用變數時,要在變數名前加上字首"$",使用echo檢視變數值

echo $A

變數賦值

1、定義時賦值:變數=值(注意等號兩邊都不能有空格

A="hello world"

2、將一個命令的執行結果賦值給變數

A=`ls -l`    ##    反引號,執行裡面的命令,並將結果返回給變數A
A=$(ls -l)    ##    等價於上面

3、將一個變數賦值給另一個變數

A="hello world"
B=$A

變數疊加

AA=123
BB="$AA"456
CC=${AA}789

補充:

單引號和雙引號的區別:單引號會將所有特殊字元脫意

列出所有的變數

set

刪除變數

unset AA

注意:使用者自定義的變數,作用域為當前的shell環境

  • (2)環境變數

環境變數在當前shell和其所有的子shell中生效。如果將環境變數寫入相應的配置檔案,那麼這個環境變數就會在

所有的shell中生效

export 變數名=變數值 申明變數
作用域:當前shell以及所有的子shell
  • (3)位置引數變數

  • (4)預定義變數

  • read命令

格式:read [選項] 值

read -p(提示語句) -n(字元個數) -t(等待時間,單位為秒) -s(隱藏輸入)

  • 運算子

Num1=11
Num2=22
Sum=$Num1+$Num2
echo Sum

格式:expr m + n(注意運算子前後必須要有空格) 或 $((m+n))

expr 3 + 5
echo `expr 3 \* 5`(\是轉移符)

計算 (2+3)*4

##    第一種方式
S=`expr 2 + 3`
expr $S \* 4

##    第二種方式
expr `expr 2 + 3` \* 4

##    第三種方式
echo $(((2+3)*4))

補充:$()和${}的區別

$()的用途和反引號``一樣,表示優先執行的命令

${}則是取變數

$((運算內容)) 適用於數值運算

  • 條件測試

內建test命令

內建test命令常用操作符號[]表示,將表示式寫在[]裡面,如下:

[ expression ] ,(注意:表示式首尾都要留空格)

或者 test expression

測試範圍:整數、字串、檔案

表示式的結果為真,則test的返回值為0,反之為1

字串測試:

test  str1 == str2    測試字串是否相等 =

test  str1 != str2    測試字串是否不相等
test  str1            測試字串是否不為空
test  -n str1     測試字串是否不為空  注意str1加雙引號和不加的區別
test  -z  str1    測試字串是否為空

整數測試:

test   int1 -eq  int2    測試整數是否相等 equals
test   int1 -ge  int2    測試int1是否>=int2
test   int1 -gt  int2    測試int1是否>int2
test   int1 -le  int2    測試int1是否<=int2
test   int1 -lt  int2    測試int1是否<int2
test   int1 -ne  int2    測試整數是否不相等

檔案測試:

test  -d  file ;echo $?  指定檔案是否目錄

test  –e  file ;echo $?    檔案是否存在 exists
test  -f  file  ;echo $?   指定檔案是否常規檔案
test –L File   ;echo $?  檔案存在並且是一個符號連結 


test  -r  file    指定檔案是否可讀
test  -w  file    指定檔案是否可寫

test  -x  file    指定檔案是否可執行

多重條件測試:

條件1 –a 條件2 邏輯與  兩個都成立,則為真

條件1 –o 條件2 邏輯或   只要有一個為真,則為真

! 條件                邏輯非    取反

  • 流程控制語句

  • if/else 命令

1、單分支if條件語句

if [ 條件判斷式 ]

    then

        程式

fi   

或者

if [ 條件判斷式 ] ; then 

    程式

fi

單分支條件語句需要注意幾個點

if語句使用fi結尾,和一般語言使用大括號結尾不同。

[ 條件判斷式 ] 就是使用test命令判斷,所以中括號和條件判斷式之間必須有空格

then後面跟符號條件之後執行的程式,可以放在[]之後,用“;”分割,也可以換行寫入,就不需要";"了。

2、多分支if條件語句

if [ 條件判斷式1 ]

    then

        當條件判斷式1成立時,執行程式1

elif  [ 條件判斷式2 ] 

    then      

        當條件判斷式2成立時,執行程式2

...省略更多條件

else

    當所有條件都不成立時,最後執行此程式

fi

case語句

case命令是一個多分支的if/else命令,case變數的值用來匹配value1,value2,value3等等。

case 變數 in
PAT1)
    執行語句
    ;;
PAT2)
    執行語句
    ;;
*)
    預設執行語句
    ;;
esac

  • for 迴圈

第一種:

for N in 1 2 3

do

echo $N

donefor N in 1 2 3; do echo $N; donefor N in {1..3}; do echo $N; done

第二種:

for ((i = 0; i <= 5; i++))

do

echo "welcome $i times"

donefor ((i = 0; i <= 5; i++)); do echo "welcome $i times"; done

  • while迴圈

while [ expression ]

do

執行語句

...

done

或者

while ((expression))

do

執行語句

...

done

  • 自定義函式

函式的格式如下:

第一種:

函式名()

{

命令1…..

命令2….

return 返回值變數

}

第二種:

[ function ] funname [()]    

{

  action;

  [return int;]

}

第三種

function funname {

  action;

  return

}

函式的呼叫: 直接函式名就可以呼叫函式

注意:

如果函式名後沒有(),在函式名和{ 之間,必須要有空格以示區分。

  • 指令碼除錯

sh -x script
這將執行該指令碼並顯示所有變數的值。

在shell腳本里新增

set -x 對部分指令碼除錯
sh -n script
不執行指令碼只是檢查語法的模式,將返回所有語法錯誤。

sh –v script

執行並顯示指令碼內容

  • cut

cut命令是用來剪下文字檔案裡的資料,文字檔案可以是欄位型別或是字元型別。下面給出應用例項:
    /> cat /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    ... ...
    /> cut -d : -f 1,5 /etc/passwd     #-d後面的冒號表示欄位之間的分隔符,-f表示取分割後的哪些欄位
    root:root                                 #這裡取出的是第一個和第五個欄位。
    bin:bin
    daemon:daemon
    adm:adm
    ... ...
    /> cut -d: -f 3- /etc/passwd       #從第三個欄位開始顯示,直到最後一個欄位。
    0:0:root:/root:/bin/bash
    1:1:bin:/bin:/sbin/nologin
    2:2:daemon:/sbin:/sbin/nologin
    3:4:adm:/var/adm:/sbin/nologin
    4:7:lp:/var/spool/lpd:/sbin/nologin
    ... ...    
    這裡需要進一步說明的是,使用cut命令還可以剪下以字元數量為標量的部分字元,該功能通過-c選項實現,其不能與-d選項共存。
    /> cut -c 1-4 /etc/passwd          #取每行的前1-4個字元。
    /> cut -c-4 /etc/passwd            #取每行的前4個字元。 
    root
    bin:
    daem
    adm:
    ... ...
    /> cut -c4- /etc/passwd            #取每行的第4個到最後字元。
    t:x:0:0:root:/root:/bin/bash
    :x:1:1:bin:/bin:/sbin/nologin
    mon:x:2:2:daemon:/sbin:/sbin/nologin
    :x:3:4:adm:/var/adm:/sbin/nologin
    ... ...
    /> cut -c1,4 /etc/passwd           #取每行的第一個和第四個字元。
    rt
    b:
    dm
    a:
    ... ...
    /> cut -c1-4,5 /etc/passwd        #取每行的1-4和第5個字元。
    root:
    bin:x
    daemo
    adm:x

  • awk和sed

sed

sed是一個很好的檔案處理工具,本身是一個管道命令,主要是以行為單位進行處理,可以將資料行進行替換、刪除、新增、選取等特定工作,下面先了解一下sed的用法

sed命令列格式為:
sed [-nefri] ‘command’ 輸入文字

常用選項:

  • -n:使用安靜模式。在一般sed用法中,所有的資料一般都會被列出到螢幕上,如果加上-n引數後,只有經過sed特殊處理的那一行才會被列出來。
  • -e:值接在指令行模式上進行sed的工作編輯。
  • -f:-f filename 可以執行filename內的sed動作。
  • -r:支援擴充套件表示式
  • -i:直接修改讀取的檔案內容。

常用命令:

  • a:新增
  • c:取代,後面可以接字串
  • d:刪除
  • i:插入
  • p:列印,通常與sed -n一起
  • s:取代,可以搭配正規表示法

例項:

刪除某行:

sed '1d' test.txt    # 刪除第一行
sed '$d' test.txt     #刪除最後一行
sed '1,2d' test.txt  # 刪除第一行到第二行
sed '2,$d' test.txt # 刪除第二行到最後一行

顯示某行:

sed -n '1p' test.txt    # 顯示第一行
sed -n '$p' test.txt     #顯示最後一行
sed -n '1,2p' test.txt  # 顯示第一行到第二行
sed -n '2,$p' test.txt # 顯示第二行到最後一行

使用模式進行查詢

sed -n '/test/p' test.txt    # 查詢包括test所在的行
sed -n '/\$/p'    test.txt    # 查詢包括$所在的行

增加一行或多行字串

sed '1a hello' test.txt    # 在第一行新增一行hello
sed '1,3a hello' test.txt    # 在第一行到第三行新增一行hello

代替一行或多行

sed '1c hello' test.txt    # 第一行替換為hello
sed '1,3c hello' test.txt    # 第一行和第三行替換為hello

代替一行中的某部分

sed -in '/name=/p' test.txt | sed 's/name=//g'        #將name=刪除
sed -i 's/name=/name/g' `grep -rl ./`            #批量修改目錄下的檔案的欄位

刪除匹配行

sed -i '/匹配字元/d' 檔案        #刪除檔案中含有匹配字元的行

替換匹配行中的某個字串

sed -i '/匹配字串/s/需要替換的字串/替換後的字串/g' 檔案

awk

sed常用於一整行資料的處理,awk則更傾向於將一行資料分為多個欄位進行處理

選項說明:

 awk -F "字串"  以某個字串為分隔符進行分割 

例子:

檔案:test.txt

a=$(cat test.txt | awk -F "=" '{print$1}')        #以“=”為分隔符,取每行的第一個欄位

結果:

常用的內建變數:

NR        #行數
NF        #列數