1. 程式人生 > 實用技巧 >shell程式設計筆記

shell程式設計筆記

shell就是以檔案形式執行一些shell命令的指令碼。

sh檔案執行方式

  • bash aa.sh

  • source aa.sh

  • ./aa.sh 如果以此種方式執行指令碼,這個指令碼必須要有可執行許可權

    chomd a+x aa.sh 給檔案賦權 執行許可權

指令碼第一行

  • #!/bin/sh

  • #!/bin/bash

  • #!/usr/bin/env bash

python 的第一行是!/usr/bin/env python

第一行的註釋,電腦在執行指令碼時,會解析。用來表示預設的指令碼命令

第一個shell指令碼

shell.sh 檔案內容如下:

#!/bin/bash   
a=10    
echo $a
echo 'hello$a'
echo I am `whoami`
echo "good afternoon$a"

 執行檔案 bash shell.sh

執行結果如下:

10
hello$a
I am ftpuser
good afternoon10

解析:

定義變數的時候 a=10 等號前後不能有空格

引用變數使用 $ 符號

單引號、雙引號、反引號的區別:

單引號:原樣輸出。可以看出以上程式碼 echo 'hello$a' 輸出結果為hello$a

雙引號:雙引號裡邊的內容會讀取變數的值

反引號:反引號裡邊的內容會被解釋成linux命令。如上命令 `whoami` 是linux命令

變數

變數種類

  1. 位置變數:$1 $2 ......$n 表示第n個引數的值
  2. 預定義變數 : 主要是$的使用

    1.     shell.sh 檔案內容

      # $的使用
      echo $0
      echo '$1的值'$1
      echo '$2的值'$2
      echo '$#的值'$#
      echo '$*的值'$*
      echo '$@的值'$@
      echo '$?的值'$?
      echo $(whoami)
      echo $((1+2))
      

        

        執行shell檔案

        bash shell.sh 12 23 aa 傳入3個引數

      執行結果:

      shell.sh
      $1的值12
      $2的值23
      $#的值3
      $*的值12 23 aa
      $@的值12 23 aa
      $?的值0

      ftpuser
      3

      總結: $0 是指檔名稱

      $1 是指傳入的第一個引數的值

      $*、$@ 是指輸出所有傳入引數的值

      $?是指上個程式執行的結果,成功為0,不成功為其他。

      $# 是指引數個數

      $(命令)是指執行括號裡的命令 相當於 `whoami`

      $((表示式)) 計算表示式的值,需要用2個小括號

          

  3. 環境變數:

定義環境變數:export x=aa

要取檔案裡的環境變數的值,需要使用source來執行檔案,然後echo $x才會出來結果

#環境變數的使用
export X=aaa

  執行檔案:

source shell.sh

執行完後列印X的值:

echo $X 會輸出aaa的值。

如果使用bash執行該指令碼,則不會打印出X的值

    修改環境變數:

      如果將一個命令 從原來的檔案下/usr/bin挪走,挪到/home/chris/mybin 這個目錄下。那麼如果使用該命令的話會報錯命令未找到,如何解決呢?

      export PATH=$PATH:/home/chris/mybin 在原有的環境變數下加上現在命令所在的目錄即可。

      但是這是暫時的,如果需要持久化,需要改~/.bashrc檔案內容,最後一列加上

      export PATH=$PATH

      然後執行該檔案 source ~/.bashrc 即可

變數運算

expr 1 + 2 注意有空格,否則不是運算結果值

或者是如下寫法

$((1+2)) 多個表示式用逗號隔開

$[1+2]

-bash-3.2$ a=((1+2))

-bash-3.2$ echo a

3

 if語句的基本使用 

  • 語法結構
    • if conditions; then  
          語句塊
      else
          語句塊
      fi
      

        條件後邊的分號不加也行

  • 數值比較
    • -eq 等於 -ne不等於
    • -lt 小於 -gt 大於
    • -le 小於等於 -ge 大於等於
    • if [ 3 -gt 2 ]
      then
          echo '3>2'
      else
          echo '3不等於2'
      fi
      

        注意:if後邊的條件 用中括號。中括號前後必須有空格。

  • 字串比較
      • read -p "請輸入一個字串" x
        read -p "請再輸入一個字串" y
        if [ $x = $y ];
        then
            echo 'x=y'
        else
            echo 'x!=y'
        fi
        

          != 不等於 [[ a>b ]] 大於和小於要用2箇中括號。條件中等號兩邊也必須要有空格

  • 判斷是否是檔案
read -p "請輸入一個路徑" path
if [ -d $path ]
then
    echo '是資料夾'
else
    echo '不是資料夾'
fi

  -d 判斷是否是資料夾。還有判斷是否是檔案等,可以自行查詢瞭解。

case語句

read -p '輸入一個值' op
case $op in
	1)
		echo 新增使用者
		;;
	2)
		echo 刪除使用者
		;;
	3)
		echo 查詢使用者
		;;
	*)
		echo 無操作
esac

  case只判斷等於的情況

for迴圈語句

for迴圈有2個方式

  1. for i in `seq 1 10`
    1. do
      1. 語句塊
    2. done
  2. for ((i=0;i<=10;i++))

do

  語句塊

done

#for迴圈的使用
for i in `seq 1 10`
do
    echo $i
done

  

函式的使用

function可以省略不寫。直接在最後傳參

function foo()
{
echo $0
echo $1
echo $2
echo $#
}
foo 12 34 45 gg

  結果:

shell.sh
12
34
4

陣列

bash shell 只支援一維陣列 [1,2,3,4,5] 類似python中的list

多維陣列就是陣列巢狀陣列

[1,2,3,[hello],5]

names=(hello good 12 34 8) #定義一個數組
echo $names[1] #結果為hello[1] 而不是good 原因是 $names 當成一個整體,預設獲取數組裡的第0個數據。解決方法:加上大括號
echo ${names[1]} #獲取第一個值
echo ${names[*]}或者echo ${names[@]} # 獲取所有值
echo ${#names[@]} #獲取長度

遍歷陣列

for i in ${names[*]}
do
echo $i
done

for((x=0;x<${#names[*]});x++)
do
echo ${names[x]}
done