一、什麼是Shell命令
Shell 腳本(shell script),是一種爲 shell 編寫的腳本程序。
業界所說的 shell 通常都是指 shell 腳本,但讀者朋友要知道,shell 和 shell script 是兩個不同的概念。
由於習慣的原因,簡潔起見,本文出現的 "shell編程" 都是指 shell 腳本編程,不是指開發 shell 自身。
二、shell環境
Shell 編程跟 JavaScript、php 編程一樣,只要有一個能編寫代碼的文本編輯器和一個能解釋執行的腳本解釋器就可以了。
Linux 的 Shell 種類衆多,常見的有:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
- ……
本教程關注的是 Bash,也就是 Bourne Again Shell,由於易用和免費,Bash 在日常工作中被廣泛使用。同時,Bash 也是大多數Linux 系統默認的 Shell。
在一般情況下,人們並不區分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同樣也可以改爲 #!/bin/bash。
三、常用shell
bash
sh
zsh
四、開始吧!一步步的寫下去!every body!
變量
注意事項:
1.=的左右沒有空格。(python中可以)
2.如果內容當中有空格需要使用單引號或者雙引號
3.雙引號⽀持轉義 $開頭的變量會被⾃動替換
變量的使用
使用echo
注意:
1.使⽤$var 或 ${var}來訪問變量。後者更爲嚴謹。$var_x ${var}_x 是不同的。
2.變量不需要定義也可以使⽤。引⽤未定義的變量,默認爲空值。
預設變量
echo $PWD
echo $USER
echo $HOME
echo $PATH
數組變量
array=(1 3 4 6)
array=(`ls`)
echo ${array[2]};
echo ${array[*]}
echo ${#array[*]}
注意:
使⽤ () 來定義數組變量,中間使⽤空格隔開
特殊符號的使用
- 雙引號⽤於括起⼀段字符串值,⽀持$var形式的變量替換
- 單引號也表⽰其內容是字符串值,不⽀持轉義
- \ 反斜線,某些情況下表⽰轉義
- ((a=a+3)) 是整數擴展。把⾥⾯的變量當作整數去處理。
- {1..10} 等價於 seq 1 10,表⽰1到10 ❖ seq 1 3 10 表⽰⽣成⼀個1到10,步進爲3
變量類型
- 字符串 a="xx"
- 數字 i=1314
- 布爾 a=true b=false
數字型變量操作
- 計算 ❖ i=1;echo $i;echo $((i+1))
- 更新 ❖ ((i=i+1));echo $i
注意:
只能進⾏整數計算
浮點數計算請使⽤ awk 'BEGIN{print 1/3}'
格式化顯⽰可以換⽤ awk 'BEGIN{printf("%.2f\n", 1/3)}'
字符串操作
取值
- ${value:offset} ${value:offset:length} 從變量中提取⼦串
- ${#value} 字符串長度
- ${#array[*]}和${#array[@]}表⽰數組中元素的個數
掐頭去尾與內容替換
- ${value#pattern} ${value##pattern} #表⽰掐頭
- ${value%pattern} ${value%%pattern} %表⽰去尾
- ${value/pattern/string} ${value//pattern/string} /表⽰替換
- #與## %與%% /與//的區別:最短匹配模式VS最長匹配模式
- ${var/#Pattern/Replacement} ${var/%Pattern/Replacement}
布爾變量
- true
- false
命令執⾏返回值 $?
任何命令執⾏都會有⼀個返回值
0表⽰正確
⾮0表⽰錯誤
判斷類型
算術判斷
❖ [ 2 –eq 2 ] 相等
❖ [ 2 –ne 2 ] 不等
❖ [ 3 –gt 1 ] ⼤於
❖ [ 3 –ge 3 ] ⼤於等於
❖ [ 3 –lt 4 ] ⼩於
❖ [ 3 –le 3 ] ⼩於等於
❖ (())也可以表⽰算術⽐較。((10>=8)) ,((10==10)),
字符串比較
❖ [ string1 = string2 ] 如果兩字符串相同,則結果爲真
❖ [ string1 != string2 ] 如果兩字符串不相同,則結果爲真
❖ [ -n "$var" ] 如果字符串不是空,則結果爲真
❖ [ -z "$var" ] 如果字符串是空,則結果爲真
❖ [[ "xxxx" == x* ]] 在表達式中表⽰0或者多個字符
❖ [[ xxx == x?? ]] 在表達式中表⽰單個字符
❖ 在引⽤變量的時候要記得加雙引號[ -z "$a"] 否則當a未定義時會語法報錯
邏輯判斷
❖ [ 2 -ge 1 -a 3 -ge 4 ];echo $? 與
❖ [ 2 -ge 1 -o 3 -ge 4 ];echo $? 或
❖ [[ 2 -ge 1 && 3 -ge 4 ]];echo $? 與
❖ [[ 2 -ge 1 || 3 -ge 4 ]];echo $? 或
❖ [ ! 2 -ge 1 ];echo $? ⾮
內置判斷
❖ -e file 如果⽂件存在,則結果爲真
❖ -d file 如果⽂件是⼀個⼦⽬錄,則結果爲真
❖ -f file 如果⽂件是⼀個普通⽂件,則結果爲真
❖ -r file 如果⽂件可讀,則結果爲真
❖ -s file 如果⽂件的長度不爲0,則結果爲真
❖ -w file 如果⽂件可寫,則結果爲真
❖ -x file 如果⽂件可執⾏,則結果爲真
❖ [[]]是[]的擴展語法,在⽼的sh⾥並不⽀持。推薦⽤[]
邏輯控制
❖ 條件 if
❖ 分⽀ case
❖ 循環 for while until select
❖ Break 和 continue
❖ 有⽣之年也許你只需要⽤到if、for、while
if結構
❖ if [ condition ] ; then …;fi
❖ if [ condition ] ; then …;else …;fi
❖ if [ condition ] ; then …;elif …;fi
❖ 簡單的邏輯可以使⽤ && || 去替代
❖ 條件可以⽤命令返回值代替
for循環
❖ for(( c1 ; c2 ; c3 ));
❖ do ❖ … ;
❖ done
❖ for((i=0;i<10;i++));do echo $i;done
for循環遍歷
❖ ⽤於遞歸數組,還可以遞歸以空格隔開的字符串序列。或者是某個命令的返回值。
❖ for f in $array[*]; ❖ do
❖ …..
❖ done
❖ ss="aa bb cc dd";for x in $ss;do echo $x ;done
❖ for x in `ls` ;do echo $x ;done
❖ ss=(aa bb cc "sss dd");for x in "${ss[@]}";do echo $x ;done
while循環
❖ i=0;while [ $i -lt 3 ] ;do echo $i;((i=i+1));done
❖ ⼀個有⽤的⼩技巧。⼀⾏⾏的讀取⽂件內容 while read line;do echo $line;done < /tmp/tmp
退出控制
❖ return 函數返回
❖ exit 腳本進程退出
❖ break 退出當前循環
❖ continue 跳過當前的循環,進⼊下⼀次循環。
四、Bath運行環境
shell運行環境概念
❖ bash下還可以再重新啓動⼀個shell,這個shell是sub shell,原shell會復 制⾃⾝給他。在sub shell中定義的變量,會隨着sub shell的消亡⽽消失
❖ () ⼦shell中運⾏
❖ $(ls) 表⽰執⾏ls後的結果,與``作⽤⼀致,不過可以嵌套
❖ {} 當前shell中執⾏
❖ $$ 當前腳本執⾏的pid
❖ & 後臺執⾏
❖ $!運⾏在後臺的最後⼀個作業的PID(進程ID)
shell環境變量
❖ Shell⾸先是⼀個⼯作環境,有很多變量可以供我們使 ⽤。
❖ set 可以獲得當前的所有變量
❖ env可以獲得可以傳遞給⼦進程的變量
❖ export aa=bbbb 把私有變量導出
shell輸入輸出
❖ Read ⽤來讀取輸⼊,並賦值給變量
❖ echo ,printf可以簡單輸出變量。
❖ > file 將輸出重定向到另⼀個⽂件
❖ >> 表⽰追加 等價於tee -a ❖ < file 輸⼊重定向
❖ | 表⽰管道,也就是前⼀個命令的輸出傳⼊下⼀個命令 的輸⼊
文件描述符
❖ 輸⼊⽂件—標準輸⼊0
❖ 輸出⽂件—標準輸出1
❖ 錯誤輸出⽂件—標準錯誤2
❖ curl ❖ 使⽤ 2>&1 >/tmp/tmp < /tmp/tmp
通配
❖ Bash可以⾃動擴展特定的關鍵詞
❖ echo * 在shell中表⽰當前⽂件 ❖ echo ??? ❖ 放⼊到引號中可以避免轉義 ❖ echo "* ????"