Linux學習之路--shell學習

 

shell基礎知識

什麼是Shell

Shell是命令解釋器(command interpreter),是Unix操做系統的用戶接口,程序從用戶接口獲得輸入信息,shell將用戶程序及其輸入翻譯成操做系統內核(kernel)可以識別的指令,而且操做系統內核執行完將返回的輸出經過shell再呈現給用戶,下圖所示用戶、shell和操做系統的關係:java

 

Shell也是一門編程語言,即shell腳本,shell是解釋執行的腳本語言,可直接調用linux命令。 .java -> .classlinux

一個系統能夠存在多個shell,能夠經過cat /etc/shells命令查看系統中安裝的shell,不一樣的shell可能支持的命令語法是不相同的shell

Shell種類

操做系統內核(kernel)與shell是獨立的套件,並且均可被替換:express

不一樣的操做系統使用不一樣的shell;apache

同一個kernel之上可使用不一樣的shell。編程

常見的shell分爲兩大主流:vim

sh:Linux經常使用的 bash

Bourne shell(sh) ,Solaris,hpux默認shellapp

Bourne again shell(bash) ,Linux系統默認shellless

csh: Unix經常使用的

C shell(csh)

tc shell(tcsh)

查看使用Shell

 

Shell環境定義

臨時環境變量

所謂臨時變量是指在用戶在當前登錄環境生效的變量,用戶登錄系統後,直接在命令行上定義的環境變量便只能在當前的登錄環境中使用。當退出系統後,環境變量將不能下次登錄時繼續使用。

 

將環境變量永久生效

經過將環境變量定義寫入到配置文件中,用戶每次登錄時系統自動定義,則無需再到命令行從新定義。定義環境變量的常見配置文件以下:

/etc/profile  針對系統全部用戶生效,此文件應用於全部用戶每次登錄系統時的環境變量定義   系統環境變量

$HOME_name/.bash_profile  針對特定用戶生效,$HOME爲用戶的宿主目錄,當用戶登錄系統後,首先繼承/etc/profile文件中的定義,再應用$HOME/.bash_profile文件中的定義。 用戶環境變量

系統預約義的環境變量

系統環境變量對全部用戶有效,如:$PATH、$HOME、$SHELL、$PWD等等,以下用echo命令打印上述的系統環境變量:

 

shell腳本編程

同傳統的編程語言同樣,shell提供了不少特性,這些特性可使你的shell腳本編程更爲有用。

建立Shell腳本

一個shell腳本一般包含以下部分:

首行

第一行內容在腳本的首行左側,表示腳本將要調用的shell解釋器,內容以下:

#!/bin/bash

#!符號可以被內核識別成是一個腳本的開始,這一行必須位於腳本的首行,/bin/bash是bash程序的絕對路徑,在這裏表示後續的內容將經過bash程序解釋執行。

建立腳本三種方式

#echo 「」> firsht.sh

#touch firsht.sh

#vim firsth.sh

 

註釋

註釋符號# 放在需註釋內容的前面,以下:

 

內容

可執行內容和shell結構

 

Shell腳本的權限

通常狀況下,默認建立的腳本是沒有執行權限的

 

沒有權限不能執行,須要賦予可執行權限

 

Shell腳本的執行

1 輸入腳本的絕對路徑或相對路徑

       /root/helloWorld.sh

       ./helloWorld.sh

2 bash或sh +腳本

       bash /root/helloWorld.sh

       sh helloWorld.sh

注:當腳本沒有x權限時,root和文件全部者經過該方式能夠正常執行。

 

3 在腳本的路徑前再加". " 或source

       source /root/helloWorld.sh

       . ./helloWorld.sh

區別:第一種和第二種會新開一個bash,不一樣bash中的變量沒法共享

另起一個shell  #bash

 

可是使用第三種方式 腳本.sh 這種方式是在同一個shell裏面執行的。

 

可使用pstree查看

source eg.sh

Shell變量

變量:是shell傳遞數據的一種方式,用來表明每一個取值的符號名。

當shell腳本須要保存一些信息時,如一個文件名或是一個數字,就把它存放在一個變量中。

變量設置規則:

1,變量名稱能夠由字母,數字和下劃線組成,可是不能以數字開頭,環境變量名建議大寫,便於區分。

2,在bash中,變量的默認類型都是字符串型,若是要進行數值運算,則必須指定變量類型爲數值型。

3,變量用等號鏈接值,等號左右兩側不能有空格

4,變量的值若是有空格,須要使用單引號或者雙引號包括。//注意要是英文輸入法那種

 

變量分類

Linux Shell中的變量分爲用戶自定義變量,環境變量,位置參數變量和預約義變量

能夠經過set命令查看系統中存在的全部變量

系統變量:保存和系統操做環境相關的數據。$HOME、$PWD、$SHELL、$USER等等

位置參數變量:主要用來向腳本中傳遞參數或數據,變量名不能自定義,變量做用固定。

預約義變量:是Bash中已經定義好的變量,變量名不能自定義,變量做用也是固定的。

用戶自定義變量

用戶自定義的變量由字母或下劃線開頭,由字母,數字或下劃線序列組成,而且大小寫字母意義不一樣,變量名長度沒有限制。

設置變量:

習慣上用大寫字母來命名變量。變量名以字母表示的字符開頭,不能用數字。

變量調用

在使用變量時,要在變量名前加上前綴「$」.

使用echo 命令查看變量值。eg:echo $A

變量賦值:

1,定義時賦值:

變量=值

等號兩側不能有空格

eg:

STR="hello world"

A=9

 

2, 將一個命令的執行結果賦給變量

A=`ls -la` 反引號,運行裏面的命令,並把結果返回給變量A

A=$(ls -la) 等價於反引號

eg: aa=$((4+5))

bb=`expr 4 + 5 `

3,將一個變量賦給另外一個變量

eg : A=$STR

變量疊加

eg:#aa=123

eg:#cc="$aa"456

eg:#dd=${aa}789

 

單引號和雙引號的區別:

現象:單引號裏的內容會  所有輸出,而雙引號裏的內容會有變化

緣由:單引號會將全部特殊字符脫意

NUM=10    

SUM="$NUM hehe"     echo $SUM     輸出10 hehe

SUM2='$NUM hehe'     echo $SUM2    輸出$NUM hehe

列出全部的變量:

# set

刪除變量:

# unset  NAME

eg :

# unset A 撤銷變量 A

# readonly B=2 聲明靜態的變量 B=2 ,不能 unset

 

 

用戶自定義的變量,做用域爲當前的shell環境。

 

環境變量

用戶自定義變量只在當前的shell中生效,而環境變量會在當前shell和其全部子shell中生效。若是把環境變量寫入相應的配置文件,那麼這個環境變量就會在全部的shell中生效。

export 變量名=變量值   申明變量

做用域:當前shell以及全部的子shell

位置參數變量

$n

n爲數字,$0表明命令自己,$1-$9表明第一到第9個參數,

十以上的參數須要用大括號包含,如${10}。

$*

表明命令行中全部的參數,把全部的參數當作一個總體。以"$1 $2 … $n"的形式輸出全部參數

$@

表明命令行中的全部參數,把每一個參數區分對待。以"$1" "$2" … "$n" 的形式輸出全部參數

$#

表明命令行中全部參數的個數。添加到shell的參數個數

 

 

shift指令:參數左移,每執行一次,參數序列順次左移一個位置,$# 的值減1,用於分別處理每一個參數,移出去的參數再也不可用

$* 和 $@的區別

$* 和 $@ 都表示傳遞給函數或腳本的全部參數,不被雙引號" "包含時,都以"$1" "$2" … "$n" 的形式輸出全部參數

當它們被雙引號" "包含時,"$*" 會將全部的參數做爲一個總體,以"$1 $2 … $n"的形式輸出全部參數;"$@" 會將各個參數分開,以"$1" "$2" … "$n" 的形式輸出全部參數

shell腳本中執行測試:

 

 

輸出結果:

 

預約義變量

$? 

執行上一個命令的返回值   執行成功,返回0,執行失敗,返回非0(具體數字由命令決定)

$$

當前進程的進程號(PID),即當前腳本執行時生成的進程號

$!

後臺運行的最後一個進程的進程號(PID),最近一個被放入後臺執行的進程   &

# vi pre.sh

pwd >/dev/null

echo $$

 

ls /etc  >/dev/null &

echo $!

 

Linux文件默認是沒有x權限的 而文件是有的

 

 

read命令

read [選項] 值

read -p(提示語句) -n(字符個數) -t(等待時間,單位爲秒) –s(隱藏輸入)   對應密碼那些輸入

eg:

read –t 30 –p 「please input your name: 」 NAME

echo $NAME

read –s –p 「please input your age : 」 AGE

echo $AGE

read –n 1 –p 「please input your sex  [M/F]: 」 GENDER

echo $GENDER

按住Ctrl +退格 才能夠退

運算符

num1=11

num2=22

sum=$num1+$num2

echo $sum

格式 :expr m + n 或$((m+n)) 注意expr運算符間要有空格

expr命令:對整數型變量進行算術運算

(注意:運算符先後必需要有空格) 

expr 3 + 5   
expr 3 – 5

echo `expr 10 / 3`            

10/3的結果爲3,由於是取整
expr  3 \* 10    

\ 是轉義符

計算(2 +3 )×4 的值

1 .分步計算
       S=`expr 2 + 3`
       expr $S \* 4

2.一步完成計算

       expr `expr 2 + 3` \* 4

       S=`expr \`expr 2 + 3\`  \* 4`  

       echo $S

       或

        echo $(((2 + 3) * 4))

$()與${}的區別

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

eg:echo $(ls a.txt)

${ } 就是取變量了  eg:echo ${PATH}

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

eg: echo $((3+1*4))

條件測試

內置test命令

內置test命令經常使用操做符號[]表示,將表達式寫在[]中,以下:

[ expression ]    注意空格

或者:

test expression

注意:expression首尾都有個空格

eg: [  ] ;echo $?

測試範圍:整數、字符串、文件

表達式的結果爲真,則test的返回值爲0,不然爲非0。

當表達式的結果爲真時,則變量$?的值就爲0,不然爲非0

 

字符串測試:

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

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

eg:

name=linzhiling

[ 「$name」 ] && echo ok

; 命令鏈接符號

&& 邏輯與 條件知足,才執行後面的語句

[ -z 「$name」 ] && echo  invalid  || echo ok

||  邏輯或,條件不知足,才執行後面的語句

test 「$name」 == 」yangmi」 && echo ok  || echo  invalid

 

整數測試:

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    測試整數是否不相等

eg:

test 100 –gt 100

test 100 –ge 100

以下示例兩個變量值的大小比較:

 

-gt表示greater than大於的意思,-le表示less equal表示小於等於。

 

 

文件測試:

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    指定文件是否可執行

 

 

eg:

test -d  install.log

test –r install.log

test –f xx.log ; echo $?

[ -L service.soft  ] && echo 「is a link」

test -L /bin/sh ;echo $?

[ -f /root ] && echo 「yes」 || echo 「no」

多重條件測試:

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

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

! 條件                邏輯非    取反

eg:

num=520

[ -n 「$num」 –a 「$num」 –ge 520 ] && echo 「marry you」 || echo 「go on」

age=20

pathname=outlog

[ ! -d「$ pathname」] &&  echo usable || echo  used

流程控制語句

if/else命令

1, 單分支if條件語句

if [ 條件判斷式 ]

    then

        程序

fi   

或者

if [ 條件判斷式 ] ; then 

    程序

fi

eg:#!/bin/sh

if  [ -x  /etc/rc.d/init.d/httpd ]

    then

    /etc/rc.d/init.d/httpd restart

fi

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

if語句使用fi結尾,和通常語言使用大括號結尾不一樣。

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

then後面跟符號條件以後執行的程序,能夠放在[]以後,用「;」分割,也能夠換行寫入,就不須要";"了。

2,多分支if條件語句

if [ 條件判斷式1 ]

    then

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

elif  [ 條件判斷式2 ] 

    then      

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

...省略更多條件

else

    當全部條件都不成立時,最後執行此程序

fi

示例:

read -p "please input your name: " NAME

eg:

#!/bin/bash

read -p "please input your name:"  NAME

#echo  $NAME

if [ $NAME == root ]

        then

                echo "hello ${NAME},  welcome !"

        elif [ $NAME == tom ]

                then

                        echo "hello ${NAME},  welcome !"

        else

                echo "SB, get out here !"

fi

case命令

case命令是一個多分支的if/else命令,case變量的值用來匹配value1,value2,value3等等。匹配到後則執行跟在後面的命令直到遇到雙分號爲止(;;)case命令以esac做爲終止符。

格式


#!/bin/bash

case $1 in

start)

echo "starting"
;;

Stop)

echo "stoping"
;;

*)

echo "Usage: {start|stop}"

esac

for循環

for循環命令用來在一個列表條目中執行有限次數的命令。好比,你可能會在一個姓名列表或文件列表中循環執行同個命令。for命令後緊跟一個自定義變量、一個關鍵字in和一個字符串列表(能夠是變量)。第一次執行for循環時,字符串列表中的第一個字符串會賦值給自定義變量,而後執行循環命令,直到遇到done語句;第二次執行for循環時,會右推字符串列表中的第二個字符串給自定義變量,依次類推,直到字符串列表遍歷完。

第一種:

for N in 1 2 3

do

echo $N

done

for N in 1 2 3; do echo $N; done

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

第二種:

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

do

echo "welcome $i times"

done

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

練習:計算從1到100的加和。

 

 

while循環

while命令根據緊跟其後的命令(command)來判斷是否執行while循環,當command執行後的返回值(exit status)爲0時,則執行while循環語句塊,直到遇到done語句,而後再返回到while命令,判斷command的返回值,當得打返回值爲非0時,則終止while循環。

第一種

while expression

do

command

done

練習:求1-10 各個數的平方和

 

 

第二種方式:

 

 

自定義函數

函數表明着一個或一組命令的集合,表示一個功能模塊,經常使用於模塊化編程。

如下是關於函數的一些重要說明:                                 

在shell中,函數必須先定義,再調用

使用return value來獲取函數的返回值

函數在當前shell中執行,可使用腳本中的變量。

函數的格式以下:

函數名()

{

命令1…..

命令2….

return 返回值變量

}

[ function ] funname [()]    

{

  action;

  [return int;]

}

function start()  / function start  / start()

eg:

 

 

注意:

若是函數名後沒有(),在函數名和{ 之間,必需要有空格以示區分。

函數返回值,只能經過$? 系統變量得到,能夠顯示加:return 返回值,若是不加,將以最後一條命令運行結果,做爲返回值。 return後跟數值n(0-255)

腳本調試

sh -x script
這將執行該腳本並顯示全部變量的值。

在shell腳本里添加  

set -x  對部分腳本調試
sh -n script
不執行腳本只是檢查語法的模式,將返回全部語法錯誤。

sh –v script

執行並顯示腳本內容

 

 

awk和sed

cut [選項]  文件名        默認分割符是製表符

選項:

    -f 列號:    提取第幾列

    -d 分隔符:    按照指定分隔符分割列

 

eg:#cut -f  2  aa.txt   提取第二列

eg:#cut -d ":" -f 1,3 /etc/passwd  以:分割,提取第1和第3列

eg:#cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1    獲取全部可登錄的普通用戶用戶名

cut的侷限性    不能分割連續空格   df -h  不能使用cut分割

df -h | grep sda1 | cut -f 5

 

awk

一個強大的文本分析工具

把文件逐行的讀入,以空格爲默認分隔符將每行切片空格能夠是連續的空格,切開的部分再進行各類分析處理。

語法:awk ‘條件1{動做1}條件2{動做2}...’文件名

條件(Pattern):

通常使用關係表達式做爲條件: >   >=  <=等

動做(Action):

格式化輸出

流程控制語句

eg:#df -h | awk '{print $1 "\t" $3}'      顯示第一列和第三列

print 有自動換行

printf 不能換行

FS內置變量 //默認第一行不會進行分割

eg:# cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"} {print $1 "\t"$3 }'    輸出可登錄用戶的用戶名和UID,這裏使用FS內置變量指定分隔符爲:,並且使用BEGIN保證第一行也操做,由於awk命令會在讀取第一行後再執行條件

指定分隔符還能夠用-F更簡單

eg:# cat /etc/passwd | grep "/bin/bash" | awk -F:  '{print $1 "\t"$3 }'   效果同上

eg:判斷一下根目錄的使用狀況

#df -h |grep sda1 | awk '{print $5}' | awk -F% '{print $1} $1<80{print "info"}$1>80{print "warning"}'

BEGIN  在全部數據讀取以前執行

eg:#awk 'BEGIN {printf "first Line \n"} {printf $2 }' aa.txt     在輸出以前使用BEGIN輸出內容

 

END 在全部數據執行以後執行

eg:#awk 'END {printf "The End \n"} {print $2}' aa.txt   全部命令執行完後,輸出一句"The End"

# df -h | grep sda2 | awk '{print $5}' | awk -F% '{print $1}'

# df -h | grep sda2 | awk '{print $5}' | cut -d"%" -f 1

獲取全部用戶信息裏的用戶名:

cat /etc/passwd | awk -F: '{print $1}'

awk -F: '{print $1}' /etc/passwd

獲取當前機器的ip地址:

# ifconfig eth0 | grep 'inet addr' | awk -F: '{print $2}' | awk '{print $1}'

 

sed: stream editor 

s e d是一個非交互性文本編輯器。它編輯文件或標準輸入導出的文本拷貝。標準輸入可 能是來自鍵盤、文件重定向、字符串或變量,或者是一個管道的文本。

注意: s e d 並不與初始化文件打交道, 它操做的只是一個拷貝,而後全部的改動若是沒有重定向到一個文件,將輸出到屏幕。

語法:sed [選項]’[動做]’ 文件名

經常使用選項:

-n  使用安靜(silent)模式。顯示通過sed特殊處理的數據。

-e  容許多點編輯。

-i  直接修改讀取的檔案內容,而不是由屏幕輸出。

命令

功能描述

a\

新增, a 的後面能夠接字串,在下一行出現

c\

替換

d

刪除

i\

插入, i 的後面能夠接字串

p

打印

s

查找並替換,例如 1,20s/old/new/g

 

eg:

sed '2p' sed.txt    顯示第二行和全部數據

sed -n '2,3p' sed.txt   顯示第二和第三行

df -h | sed -n '1p'      接收命令結果數據

sed ‘2a liuyifei’sed.txt 在第二行後面添加數據

sed ‘4i fengjie \

canglaoshi’sed.txt 在第4行以前添加兩行數據

sed ‘2c this is replace’sed.txt 替換第二行數據

sed ‘s/it/edu360/g’ sed.txt  把sed.txt文件中的it替換爲edu360,並輸出

sed -e '1s/1/34/g;3s/yangmi//g' sed.txt    同時進行多個替換

sed –i ‘s/it/edu360/g’ sed.txt   要想真正替換,須要使用-i參數

 

 

使用sed獲取機器的ip地址

ifconfig eth0 | grep 'inet addr'| sed 's/^.*addr://g' | sed 's/  Bcast.*$//g'

 

定時器

crontab 命令容許用戶提交、編輯或刪除相應的做業。每個用戶均可以有一個crontab 文件來保存調度信息。可使用它運行任意一個 s h e l l 腳本或某個命令。

crontab命令格式

做用:用於生成cron進程所須要的crontab文件
crontab的命令格式

# crontab -e    

使用編輯器編輯當前的crontab文件。

 

  crontab文件格式
minute hour  day-of-month  month-of-year  day-of-week  commands

分< >時< >日< >月< >星期< >要運行的命令     < >表示空格

其中
    Minute              一小時中的哪一分鐘     [0~59] 
    hour                  一天中的哪一個小時        [0~23] 
    day-of-month    一月中的哪一天           [1~31] 
    month-of-year   一年中的哪一月           [1~12] 
    day-of-week      一週中的哪一天           [0~6]     0表示星期天
    commands         執行的命令 

 

書寫注意事項
1,全都不能爲空,必須填入,不知道的值使用通配符*表示任什麼時候間
2,每一個時間字段均可以指定多個值,不連續的值用,間隔,連續的值用-間隔。
3,命令應該給出絕對路徑
4,用戶必須具備運行所對應的命令或程序的權限

如何使用crontab 運行多個任務:

方法1:在crontab -e 裏 寫多個

輸入命令  crontab –e 

敲回車

 

 

開始編寫任務:

 

 

方法2:把全部的任務,寫入到一個可執行的文件

再在crontab -e裏面配置執行任務

 

 

分鐘   小時   天   月   星期   命令/腳本

示例:

eg:4點備份

0      4        *      *     *

 

eg:每週二,週五,下午6點  的計劃任務

0     18       *      *     2,5

 

eg:1到3月份,每週二週五,下午6點的計劃任務

0     18       *     1-3   2,5

 

eg:週一到週五下午,5點半提醒學生15分鐘後關機

30   17      *       *     1-5   /usr/bin/wall < /etc/issue

45   17      *       *     1-5  /sbin/shutdown -h now

 

eg:學校的計劃任務, 12點14點,檢查apache服務是否啓動

*/2  12-14  *   3-6,9-12   1-5   

eg:再添加一個備份,把/etc目錄備份到/backup下,而後把錯誤的狀況也記錄下來,正確的文件都丟到/dev/null下,看不見(至關於一個黑洞)  

*/2  12-14  *   3-6,9-12   1-5   /bin/cp -r /etc  /backup/etc.20170407 2> /backup/etc.bak.err 

/dev/null          */2表示每隔兩分鐘

 

eg:每個月 一、1 0、2 2日的4:45運行/apps/bin目錄下的backup.sh

45  4  1,10,22  *  * /apps/bin/backup.sh

 

eg:每週6、週日的 1 : 10運行一個find命令

10  1  *  *  6,0  /bin/find -name "core" -exec rm {} \;

 

eg:在天天 18:00至23 :00之間每隔30分鐘運行/apps/bin目錄下的dbcheck.sh

0,30  18-23  *  *  * /apps/bin/dbcheck.sh

 

eg:每星期六的 11:00 pm運行/apps/bin目錄下的qtrend.sh

0  23  *  *  6  /apps/bin/qtrend.sh

相關文章
相關標籤/搜索