你還不會shell腳本嗎,我來教你

這幾天也是剛學習了shell腳本的編寫,雖然他不像Python、Java那樣可以編寫很大型的項目(固然我是這麼認爲),可是在操控Linux系統方面,仍是有獨特的優點的,固然在學習過程當中咱們也能更好的瞭解Linux。接下來,就開始學習吧。後面會有幾個小例子,固然都是別的地方挪過來的,我就是代碼的搬運工,嘿嘿。喜歡學習的同志們能夠點擊Python聚焦專欄,查看更多知識。html

繁瑣的括號總結

基本概念

解釋器種類

  • 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)

在通常狀況下,人們並不區分 Bourne Shell 和 Bourne Again Shell,因此,像 #!/bin/sh,它一樣也能夠改成 #!/bin/bash。python

腳本編寫

  • 指定使用的解釋器類型
#!/bin/bash

運行方式

做爲可執行程序

chmod +x ./test.sh # 修改權限
./test.sh   # 執行

運行時必定要寫成./test.sh,由於直接寫test.sh,linux會去PATH裏尋找,而通常只有/bin,/sbin,/usr/bin,/usr/sbin等在PATH中,因此使用./test.sh告訴系統,就在本目錄下找mysql

做爲解釋器參數

  • 這種方式能夠不用在sh文件中寫明解釋器類型,寫了也是沒有用的
/bin/sh test.sh

基本語法

變量

  • 定義方式和python相似,只不過定義過程當中不容許使用空格,默認都是字符串類型linux

    • declare命令定義有類型的變量nginx

      • -i : 定義整型變量
      • -a : 定義一個數組
      • -f : 查看系統中全部定義的函數
      • -F : 查看系統中全部定義的函數名稱
      • -x : 聲明一個環境變量--在腳本文件中能夠直接使用的變量
      • 取消定義的變量:把命令減號改爲加號再執行
  • 使用時只須要使用$ / ${ }就能夠了
  • 只讀變量:在變量定義後,再使用readonly 修飾,再次賦值會報錯
  • 刪除變量:unset var_name,不能刪除只讀變量

變量數據修改

語法 說明
${var_name#規則} 從變量開頭進行匹配,將符合最短的數據刪除
${var_name##規則} 從變量開頭進行匹配,將符合最長的數據刪除
${var_name%規則} 從變量末尾進行匹配,將符合最短的數據刪除
${var_name%%規則} 從變量末尾進行匹配,將符合最長的數據刪除
${變量名/舊字符串/新字符串} 變量內容符合舊字符串,就將第一個替換
${變量名//舊字符串/新字符串} 變量內容符合舊字符串,就所有替換

字符串

  • Shell字符串正則表達式

    • 單引號:不能使用變量
    • 雙引號:可使用變量,並轉義\n等字符
    • 反引號:用於保存要執行的命令,同:$() 【點擊例子】
    • 在進行拼接的時候是能夠出現如下形式的:sql

      • "Hello, "$world""
      • 'Hello, '$world''
  • expr命令是從1開始索引,而普通的提取都是從零開始索引的
  • 求長度shell

    • 獲取字符串長度:$#var_name
    • ${#str}
    • expr lenth $str
  • 求字串索引數據庫

    • expr index $str substr_regsegmentfault

      • substr其實索引的是其每一個字符,返回最小索引的那個
  • 匹配的字串的長度

    • expr match $str substr_reg
  • 截取

    • ${str:start}
    • ${str:start:lenth}
    • ${str:(start)}/\${str: -start} start爲負數,表示從尾部開始
    • expr substr $str $start $length

數組

  • 定義:

    • array_name=(value0 value1 value2 value3) 使用空格分隔元素
    • array_name[0]=value0 / array_name[1]=value1下標能夠不連續
  • 讀取:

    • 單個讀取:${array_name[index]}
    • 所有讀取:${array_name[@]}
    • 獲取長度:

      • 數組長度:length=${#array_name[@]}/length=${#array_name[*]}
      • 單個元素長度:lengthn=${#array_name[n]}

註釋

  • 單行:#
  • 多行:

    • :<<EOF . . . EOF
    • 使用其餘符號替代EOF,如:'

函數

  • 定義

    • function func_name { }
    • func_name ( ) { }
  • 返回值

    • return : 通常返回一個整數,用於作判斷
    • echo : 用於返回數據
    • printf
  • 局部變量

    • local修飾,不進行修飾那麼函數執行後,其餘地方也可使用。
  • 函數庫

    • 文件後綴是任意的,通常爲lib
    • 通常不會賦予可執行權限
    • 第一行通常使用#!/bin/echo輸出警告信息,避免用戶執行

獲取命令行參數

  • $num:num爲要獲取的參數位置,從0開始,分別表明文件名,參數1,參數2
  • $#:傳遞到腳本的參數個數
  • &dollar;&dollar;:腳本運行的當前進程ID號
  • $!:後臺運行的最後一個進程的ID號
  • $?:顯示最後命令的退出狀態。0表示沒有錯誤,其餘任何值代表有錯誤。
  • $-:顯示Shell使用的當前選項,與set命令功能相同。
  • $* / $@:以一個單字符串顯示全部向腳本傳遞的參數。

    • 相同點:都是引用全部參數。
    • 不一樣點:只有在雙引號中體現出來。假設在腳本運行時寫了三個參數 一、二、3,,則 " * " 等價於 "1 2 3"(傳遞了一個參數),而 "@" 等價於 "1" "2" "3"(傳遞了三個參數)。

中括號的使用(通常可使用test命令替換)

  • 一個變量是否爲0, [ $var -eq 0 ]

    • ne:不等於
    • lt/gt:小於/大於
    • le/ge:小於等於/大於等於
  • 一個文件是否存在,[ -e $var ], 是不是目錄,[ -d $var ]
  • 兩個字符串是否相同, [[ $var1 = $var2 ]]
  • -a/-o:and/or
  • -e : exist
  • -r : 是否可讀
  • -w : 是否可寫
  • -n :判斷字符串長度是否非0
  • -z :判斷字符串長度是否爲0
  • $ :判斷字符串是否非空

運算符:原生bash不支持簡單的數學運算,須要使用awk和expr,expr最經常使用,而且只能進行整數運算

  • 表達式和運算符之間要有空格
  • 完整的表達式要被 包含
  • 帶有轉移的字符須要使用\修飾才能使用
  • 使用$(())中間的運算符不須要轉義而且不要求有空格,不能進行相等和不等的判斷
  • echo `expr 2 + 2` # 輸出4
  • 成立返回1,不成立返回0
  • 在 MAC 中 shell 的 expr 語法是:$((表達式)),此處表達式中的 "*" 不須要轉義符號 ""
  • 浮點數計算:bc

    • echo "scale=2;1+1.2" | bc

幾個經常使用命令

  • read命令

    • 從標準輸入中接收一行,並對修飾的變量賦值
    • read -p "請輸入一段文字:" -n 6 -t 5 -s password

      • -p 輸入提示文字
      • -n 輸入字符長度限制(達到6位,自動結束)
      • -t 輸入限時
      • -s 隱藏輸入內容
  • echo

    • -e 開啓轉義,對字符串中的轉義字符進行轉義操做,不區分單雙引號
  • printf

    • printf "%s" jim
  • test:通常用於替換中括號

    • test $num = $num2

流程控制

  • if . . . else

    • if condition
      then
          command1 
      elif condition1
      then
          command2
      else
          commandN
      fi
  • for . . . in

    • for var in data
      do
          command1
      done
  • while

    • while condition
      do
          command
      done
  • until:與while相反操做,條件爲true時退出循環
  • 死循環

    • while :
      do
          command
      done
      # 使用true
      while true
      do
          command
      done
      # 使用for
      for (( ; ; ))
  • case

    • case value in
      value1)
          command1
      ;;
      value2)
          command2
      ;;
      *)
          command2
      ;;
      esac

let執行一個或多個表達式

sed(Stream Editor)命令詳解,對查找到的數據進行處理【點擊例子】

# 語法格式:
sed [option] "pattern command" file_name
# 刪除文件第一行
sed -i '1d' file_name
  • option選項

    • n:只輸出匹配的行
    • e:須要匹配的條件,能夠指定多個-e "pattern command"
    • f:指定sed文件,用於封裝替換"pattern command"
    • r:用於支持正則表達式
    • 修改輸出內容:sed -n 's/love/like/g;p' sed.txt
    • i:修改源文件
  • pattern

    • 可使用正則表達式
    • 可使用變量,只要按照腳本使用變量就能夠:雙引號,$var_name
    • 匹配/須要進行轉義
    • 按行匹配的時候,行數在後面若是小於前一個匹配模式,那麼久只顯示知足前一個條件的行
    • =:顯示行號
  • command

    • a : 在匹配到行的下一行添加字符串
    • i :在匹配到行的上一行添加字符串
    • r :在匹配到行的下一行添加file內容
    • w :將匹配到的行寫入文件
    • d :刪除數據
    • p :打印數據
    • g :修改數據時所有匹配,3g表示從第三個開始所有修改,ig忽略大小寫
    • = :顯示匹配到的行號
  • 反向引用

    • 在使用替換字符的時候,修改內容使用&表示使用被替換的條件

      • # 在匹配到^la..jim的後面加shuai
        # &:全匹配,\1:其使用了正則的分組,因此前面須要使用小括號括起來
        sed -i 's/^la..jim/&shuai/g' sed.txt
  • 命令詳解

awk工做模式【點擊例子】

# 語法格式:
awk 'BEGIN{}pattern{commands}END{}' file_name

小例子

  • <span id="find_user_all">查詢全部用戶</span>
for user in `cat /etc/passwd | cut -d ":" -f 1`
do
    echo "$user"
done
  • <span id="start_nginx">啓動nginx</span>
nginx_num_process=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ nginx_num_process -eq 0 ];then
    systemctl start nginx
fi
  • <span id="num_add">用戶輸入num,求1-num之和</span>
while true
do
    read -p "pls input a positive number: " num
    expr $num + 1 &> /dev/null
    if [ $? -eq 0 ];then
        if [ `expr $num \> 0` -eq 1 ];then
            for((i=1;i<=$num;i++))
            do
                sum=`expr $sum + $i`
            done    
            echo "1+2+3+....+$num = $sum"
            exit
        fi
    fi
    echo "error,input enlegal"
    continue
done
  • <span id="check_nginx">檢查Nginx是否正常運行,宕機則啓動它</span>
this_pid=$$

while true
do
ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null

if [ $? -eq 0 ];then
    echo "Nginx is running well"
    sleep 3
else
    systemctl start nginx
    echo "Nginx is down,Start it...."
fi
done
  • <span id="find_mysql">查找mysql配置文件中有幾段</span>
FILE_NAME=/root/lesson/5.6/my.cnf
function get_all_segments
{
    echo "`sed -n '/\[.*\]/p' $FILE_NAME  | sed -e 's/\[//g' -e 's/\]//g'`"
}
function count_items_in_segment
{
    items=`sed -n '/\['$1'\]/,/\[.*\]/p' $FILE_NAME | grep -v "^#" | grep -v "^$" | grep -v "\[.*\]"`
    index=0
    for item in $items
    do
        index=`expr $index + 1`
    done
    echo $index
}
number=0
for segment in `get_all_segments`
do
    number=`expr $number + 1`
    items_count=`count_items_in_segment $segment`
    echo "$number: $segment  $items_count"
done
  • <span id="del_blank">刪除配置文件中全部的註釋行和空行</span>
sed -i '/[:blank:]*#/^$/d' config.cnf
  • <span id="add_not_ano">在非#註釋行前加*</span>
sed -i 's/^[^#]/\*&/g' config.cnf
  • <span id="text_insert_mysql">文本格式化數據插入mysql</span>
user=""
password=""
host=""
mysql_conn="mysql -u"$user" -p"$password" -h"$host""
IFS=":" # 內置分隔符變量
cat data.txt | while read id name birth sex
do
  $mysql_conn -e "insert into school values('$id','$name','$birth','$sex')"
done
  • <span id="script_use_ftp">腳本使用ftp</span>
ftp -inv << EOF
open ftp_ip_addr
user user_name password

put file_name
bye
EOF #必須頂格寫

小東東

  • nohub + & 後臺啓動 : nohub不間斷的運行程序,關閉窗口也不會關閉進程,&用於後臺運行
  • netstat -tnlp | grep port : 通常用於查看端口
  • &&當左側的命令返回0(成功)纔會執行右側命令
  • cut -d ":"制定分隔符
  • free -m:內存使用狀況
  • df -h:磁盤使用狀況
  • n >& m:將輸出文件 m 和 n 合併
  • n <& m:將輸入文件 m 和 n 合併
  • << tag:將開始標記 tag 和結束標記 tag 之間的內容做爲輸入
  • grep -E等同於egrep,用於擴展支持正則表達式
  • cat -n file顯示行號輸出
  • /sbin/nologin 不能夠登錄的用戶
  • [:blank:]表示空格
  • ^$表示空行
  • sh -x能夠查看執行過程
  • 根據其餘表的結構建立新表

    • create table new_table like other_table
  • mysql -B不顯示邊框 -E表示垂直顯示 -H輸出html -X輸出xml -N不顯示列名
  • mysqldumps備份mysql

    • d :只導出表結構
    • t :只導出數據,不導出建表語句
    • A :導出全部數據庫
    • B :導出一個或者多個數據庫
  • crontab定時任務
相關文章
相關標籤/搜索