1. 程式人生 > >shell指令碼從入門到精通(初級)之入門篇

shell指令碼從入門到精通(初級)之入門篇

一、變數

1. 環境變數

#!/bin/bash
# 全域性變數
echo "User Info:"
echo "user: $USER"
echo "UID : $EUID"
echo "home: $HOME"
echo “$HOSTNAME”

2. 使用者變數

變數命名規則:

  1. 由字母、數字和下劃線組成
  2. 大小寫敏感
#!/bin/bash
# 使用者變數
var1=100
var2=hello
var3="hello world"
echo "$var1 $var2 $var3"

3. 特殊變數

變數 含義
$0 當前指令碼的檔名
$n 傳遞給指令碼或函式的引數。n 是一個數字
$# 傳遞給指令碼或函式的引數個數。
$* 傳遞給指令碼或函式的所有引數。
[email protected] 傳遞給指令碼或函式的所有引數
$? 上個命令的退出狀態,或函式的返回值。
$$ 當前Shell程序ID。對於 Shell 指令碼,就是這些指令碼所在的程序ID。
#!/bin/bash
echo "Total Number of Parameters : $#"
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: 
[email protected]
" echo "Quoted Values: $*" echo "PID $$" echo "$?"

[email protected] 與 $* 的區別

$* 和 [email protected] 都表示傳遞給函式或指令碼的所有引數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有引數。
但是當它們被雙引號(" ")包含時,"$*" 會將所有的引數作為一個整體,以"$1 $2 … $n"的形式輸出所有引數;"[email protected]" 會將各個引數分開,以"$1" "$2" … "$n" 的形式輸出所有引數。

#!/bin/bash
echo ‘[email protected]:’
for i in [email protected];do
    echo $i
done
echo ‘"[email protected]:"’
for i in "[email protected]";do
    echo $i
done
echo ‘$*:’
for i in $*;do
    echo $i
done
echo ‘"$*:"’
for i in "$*";do
    echo $i
done
結果:
[email protected]:
1
2
3
"$*":
1
2
3
[email protected]:
1
2
3
"$*":
1 2 3

4. ``與$()

把命令的執行結果賦給變數的兩種方式

#!/bin/bash
time=`date +%y%m%d`
time=$(date +%y%m%d)

1. expr

#!/bin/bash
# 注意變數和=之間不能有空格,expr 和 = 之間要有一個空格
var= expr 1 + 2
echo $var

expr 及其難用,一般不用

2. [] 與 (())

#!/bin/bash
# 
var=$[ 1 + 2 ]
var=$(( 3 + 4 ))

3. bc

上述兩種只能計算整數,對於浮點數需要使用bc
在指令碼中使用bc的格式:

variable=`echo "option; expression" |bc`
#!/bin/bash
var=`echo "scale=2;5/3" | bc`
echo $var

1. if

1.1 if-then

格式:

if command
then
    command
fi

例:

#!/bin/bash
if date
then
    echo "command is succeed"
fi

1.2 if-then-else

格式:

if command
then
    command
else
     command        
fi

例:

#!/bin/bash
# 查詢系統中是否存在httpd使用者
if grep httpd /etc/passwd
then
    echo "httpd is exist"
else
    echo "httpd not find"
fi

1.3 if巢狀

格式:

if command
then
    command
elif command
    command    
else
     command        
fi

2. test

功能:

  1. 數值比較
  2. 字串比較
  3. 檔案比較

格式:

test condition
或
[ command ]     -- 更常用

2.1 數值比較

比較 描述
-eq 等於
-ge 大於等於
-gt 大於
-le 小於等於
-lt 小於
-ne 不等於

例:

#!/bin/bash
date
if [ $? -eq 0 ];then
   echo "command is succeed"
fi
# 或
if test date;then
   echo "command is succeed"
fi

2.2 字串比較

比較 描述
str1 = str2 字串是否相同
str1 != str2 字串是否不同
str1 < str2 str1是否比str2小
str1 > str2 str1是否比str2大 [ b \> a ] && echo "true" (注意>需要轉義)
-n str 字串長度非0為真 [ -n "str" ] && echo "str is not null"
-z str 字串長度為0為真 [ -z "" ] && echo "str is null"

2.3 檔案比較

比較 描述
-d file 檢查file是否存在並是一個目錄 [ -d /data ] && echo "exist"
-f file 檢查file是否存在並是一個目錄
-e file 檢查file是否存在
-r file 檢查file是否存在並可讀
-s file 檢查file是否存在並非空
-w file 檢查file是否存在並可寫
-x file 檢查file是否存在並可執行
-O file 檢查file是否存在並屬當前使用者所有
-G file 檢查file是否存在並且預設組與當前使用者相同
file1 -nt file2 file1是否比file2新
file1 -ot file2 file1是否比file2舊

2.4 符合條件

[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]

3. case

格式:

case variable in
pattern1 | pattern2) command1;;
pattern3) command2;;
*) default command;;
esca

例:

#!/bin/bash
read -p "input something: " var
case $var in
[0-9])
    echo "number";;
[a-z])
    echo "character";;
*)
    echo "other";;
esac

4. for

4.1 bash中的for

格式:

for var in list
do
    command
done

例1:檢視服務狀態

#!/bin/bash
for service in apache2 mysqld zabbix-server zabbix-agent
do
    status=$(systemctl status mysql | awk '/Active/ {print $2,$3}')
    echo $service $status
done

例2:使用萬用字元

#!/bin/bash
# 注意在$file上加“”,否則如果出現帶空格的目錄名,指令碼會出錯
for file in /tmp/*
do
    if [ -d "$file" ]
    then
        echo "$file" is a directory
    elif [ -f "$file" ]
    then
        echo "$file" is a file
    fi
done

4.2 C 語言風格的for

例:

#!/bin/bash
for (( i=1; i<=10; i++ ))
do
    echo $i
done

#!/bin/bash
# 單變數
for (( i=1; i<=10; i++ ))
do
    echo $i
done
# 多變數
for (( i=1,j=10; i<=10; i++,j-- ))
do
    echo $i $j
done

5. while

例:檢測站點狀態

#!/bin/bash

urls="
https://www.baidu.com
https://www.taobao.com
https://www.jd.com/abc
https://www.12306.cn/index/
192.168.1.111
"
for url in $urls;do
    count=0
    while [ $count -lt 3 ];do
       STATUS=$(curl -I -m 10 -o /dev/null -s -w %{http_code} $url)

       if [ $STATUS -eq 200 ];then
          echo "$url  OK"
          break 1
       fi
       count=$(($count+1))
    done
    if [ $count -eq 3 ];then
       echo "$url Error"
    fi
done

6. until

#!/bin/bash
var=10
until [ $var -eq 0 ];do
    var=$[$var-2]
    echo $var
done

7. 控制迴圈

7.1 break

#!/bin/bash
# break 跳出當前迴圈
# break n 跳出n層迴圈
for (( i=0; i<10; i++ ));do
    if [ $i -eq 5 ];then
       break
    fi
    echo $i
done

7.2 continue

四、輸入

1. 命令列引數

例1:

#!/bin/bash
echo $1+$2=$[$1+$2]

./add.sh  3 4
3+4=7

例2:shift

#!/bin/bash
# 把變數的位置向左移
while [ -n "$1" ];do
    echo $1
    shift
done

2.getopts

格式:getopts optstring variable
optstring: 選項字母,如果字母要求有引數就加一個:,要去掉錯誤訊息的話可以在optstring前加一個:
variable:儲存當前引數

#!/bin/bash
# getopts的用法
# opt 會儲存輸入的引數,如 r i
# OPTARG儲存引數值
# 引數需要一個值就在引數後面加一個: 如i:
while getopts ri: opt
do
    case "$opt" in
    i) echo "install service $OPTARG";;
    r) echo "remove all service";;
    *) echo "Unknown option: $opt";;
    esac
done
[email protected]:/# ./getopts.sh -i apache2
install service apache2
[email protected]:/# ./getopts.sh -r
remove all service
[email protected]:/# ./getopts.sh -a
./getopts.sh: illegal option -- a
Unknown option: ?

3. 獲得使用者輸入 read

3.1 普通用法

#!/bin/bash
read name
echo $name

3.2 指定提示符

#!/bin/bash
read -p "Enter your name: " name
echo "Hello $name "

3.3 指定超時時間

#!/bin/bash
if read -t 5 -p  "Enter your name: " name
then
    echo "Hello $name"
else
    echo "TIME OUT"
fi

3.4 隱藏資料

#!/bin/bash
read -s -p "Enter passwd: " passwd
echo "$passwd"

3.5 限制輸入長度

#!/bin/bash
read -n1 -p "Do you want continue[Y/N]?" answer
echo
echo "$answer"

五、輸出

顯示指令碼輸出的方法:

  1. 在顯示器上顯示
  2. 將輸出重定向到檔案
描述符 縮寫 描述
0 STDIN 標準輸入
1 STDOUT 標準輸出
2 STDERR 標準錯誤

1. 在指令碼中重定向

1. 臨時重定向

使用場景:在指令碼中生成錯誤訊息

#!/bin/bash
echo "This is an error message" >&2
echo "This is normal output"

預設情況下Linux 會將STDERR定向到STDOUT
$./error.sh
This is an error message
This is normal output
在執行指令碼的時候重定向STDERR,ERR文字就會被重定向
$ ./error.sh 2> error.log
This is normal output
$ cat error.log
This is an error message

2. 永久重定向

用exec命令告訴shell在執行指令碼期間重定向某個特定檔案描述符

#!/bin/bash
exec 2>errout
echo "This is error"
exec 1>testout
echo "testout"
echo "testout  to errout" >&2
$ ./test.sh
This is error
$ cat errout
testout  to errout
$ cat testout
testout

2. 記錄訊息

tee : 將輸出一邊傳送到顯示器一邊傳送到日誌檔案
tee 預設會覆蓋原來的檔案,可以使用-a追加

$ date | tee -a date.txt
Fri Nov 23 11:03:15 CST 2018
$ cat date.txt
Fri Nov 23 11:03:07 CST 2018
Fri Nov 23 11:03:15 CST 2018

六、函式

1.基本函式

#!/bin/bash
# 定義方式1
function foo {
    echo "This is a func"
}
# 定義方式2
bar() {
   echo "This is another func"
}
# 函式的呼叫
foo
bar
$ ./func.sh
This is a func
This is another func

2.返回值

  1. 預設退出狀態碼
#!/bin/bash
function foo {
    echo "This is a func"
}
foo
echo "Exit status is $?"
  1. 使用return命令
#!/bin/bash
function foo {
    echo "Hello world"
    return 2
}
foo
echo "Exit status is $?"
 ./func.sh
Hello world
Exit status is 2
  1. 使用函式輸出
#!/bin/bash
function foo {
    echo "Hello world"
}
foo
# 把函式的輸出賦值給變數
result=`foo`
echo "Exit status is $result"
 $./func.sh
Hello world
Exit status is Hello world

3.變數

  1. 傳參
#!/bin/bash
function status {
    systemctl status $1
}
status sshd
  1. 區域性變數與全域性變數
#!/bin/bash
# 定義全域性變數
hostname="web"
function foo {
      str="hello"
      # 使用 local 定義區域性變數
      local  user="http"
      # 可以在函式內使用全域性變數
      echo "$hostname"
      echo "$user"
}
foo
# 在函式中定義的區域性變數不能在全域性使用
echo "$str $user"
  1. 陣列變數
    如果將陣列變數作為函式引數,函式只會取陣列變數的第一個值
#!/bin/bash
function foo {
     arr=$1
     echo "The received array is ${arr[*]}"
}
myarr=(1 2 3 4 5)
foo $myarr

解決方法

#!/bin/bash
function foo {
     [email protected]
     echo "The received array is ${arr[*]}"
}
myarr=(1 2 3 4 5)
# 將該陣列變數的值分解成單個的值,然後將這些值作為函式引數使用。
foo ${myarr[*]}

1.處理訊號

1.1檢視Linux訊號

kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

在Linux程式設計時會遇到的最常見的Linux系統訊號

信 號 描 述 觸發
1 SIGHUP 掛起程序
2 SIGINT 終止程序 Ctrl + C
3 SIGQUIT 停止程序
9 SIGKILL 無條件終止程序
15 SIGTERM 儘可能終止程序
17 SIGSTOP 無條件停止程序,但不是終止程序
18 SIGTSTP 停止或暫停程序,但不終止程序 Ctrl+Z
19 SIGCONT 繼續執行停止的程序

1.2 捕捉訊號

格式:trap command signals

#!/bin/bash
trap "echo 'You Enter Ctrl + C'" SIGINT
for (( i=0; i<10; i++ ));do
    echo $i
    sleep 1
done
# ./signal.sh
0
1
^CYou Enter Ctrl + C
2
^CYou Enter Ctrl + C

2.指令碼執行

  1. 指令碼執行
    bash file.sh

    chmod +x file.sh
    ./file.sh
  2. 後臺執行指令碼
    ./test.sh &
    nohub ./test.sh &

附:退出狀態

可以使用$?檢視上一個命令的退出狀態碼
狀態碼 | 含義
--- |---
0 | 命令成功結束
1 | 通用未知錯誤
2 | 誤用shell命令
126 | 命令不可執行
127 | 沒有找到命令
128+x | Linux訊號x的嚴重錯誤
130 | 命令通過Ctrl+C終止
255 | 退出狀態碼越界

相關推薦

shell指令碼入門精通初級入門

一、變數 1. 環境變數 #!/bin/bash # 全域性變數 echo "User Info:" echo "user: $USER" echo "UID : $EUID" echo "home: $HOME" echo “$HOSTNAME” 2. 使用者變數

shell腳本入門精通中級提高

hello 一行 The 入門 href red 變量 \n 使用 shell 腳本入門到精通(中級) 一、shell 腳本的執行 二、輸出格式化 一、shell 腳本的執行 1. 腳本執行的4種方法 $ ls /tmp/test.sh /tmp/test.sh #!/bi

NS3入門學習指令碼執行例項

 ns3中使用的編譯系統是waf,所有的c++工程都需要經過waf編譯後執行,除錯時也需要waf的。 在3.1.3中還是使用C++寫指令碼,在/ns-3.1.3/examples/tutorial/的second.cc指令碼中可以看出來,在3.2.6以上版本中已經增加了python

GPU 程式設計入門精通 GPU 程式優化

博主由於工作當中的需要,開始學習 GPU 上面的程式設計,主要涉及到的是基於 GPU 的深度學習方面的知識,鑑於之前沒有接觸過 GPU 程式設計,因此在這裡特地學習一下 GPU 上面的程式設計。有志同道合的小夥伴,歡迎一起交流和學習,我的郵箱: [email protected] 。使用的是自

萌新web前端零開始1——計算機入門

    前言:這是一個萌新從零開始的學習之路,與大家分享自己的看法與見解,還請指出錯誤與遺漏點方便改正。     1.認識計算機。     計算機語言常見的有C,PHP,Ruby,Java,C#,Basic,JS,C++等,這裡我用到的是C#語言,用到的軟體是VisualStudio 2013版本。當用V

shell 指令碼 的 基本知識 IV

shell中常用的控制語句及指令碼的執行控制 一、for語句 for in do done 1)控制語句 exit 指令碼直接退出 break 退出當前迴圈;即退出for後面的還要執行 continue 提前結束迴圈內部的命令,但不終止迴

NS2入門學習tcl指令碼示例

1、示例分析 tcl語法與python相差不多,以《NS與網路模擬》中的第一個tcl指令碼為例,學習如下:#建立一個Simulator物件的例項並把它賦值給變數ns set ns [new Simulator] #開啟一個名為linktrace.tr的檔案,用來記錄模擬過程

shell指令碼程式設計學習筆記2正則表示式

編寫shell指令碼時經常用到的基本操作就是尋找包含特定文字的行,雖然用簡單的grep命令可以完成一些簡單的工作,但是正則表示式無疑是繞不開的。本文主要介紹基本正則表示式。 總的來說,正則表示式由兩部分組成:一般字元和特殊字元。特殊字元(meta)在正則表示式中往往具有特

Java怎麼通過java去呼叫並執行shell指令碼以及問題總結

背景 我們在開發過程中,大部分是java開發, 而在文字處理過程中,主要就是指令碼進行開發。 java開發的特點就是我們可以很早地進行TDDL, METAQ 等等地對接; 而指令碼開發的特點就是在進行批處理的時候非常方便。 前陣子我遇到這麼一個需求場景: 對抓

Shell指令碼中的併發1

主要記錄一下Shell指令碼中的命令的併發和序列執行。 預設的情況下,Shell指令碼中的命令是序列執行的,必須等到前一條命令執行完後才執行接下來的命令,但是如果我有一大批的的命令需要執行,而且互相又沒有影響的情況下(有影響的話就比較複雜了),那麼就要使用

GPU 程式設計入門精通 CUDA 環境安裝

博主由於工作當中的需要,開始學習 GPU 上面的程式設計,主要涉及到的是基於 GPU 的深度學習方面的知識,鑑於之前沒有接觸過 GPU 程式設計,因此在這裡特地學習一下 GPU 上面的程式設計。有志同道合的小夥伴,歡迎一起交流和學習,我的郵箱: [email protected] 。使用的是自

30個關於Shell指令碼的經典案例

對於初學者而言,因為沒有實戰經驗,寫不出來Shell指令碼很正常,如果工作了幾年的運維老年還是寫不出來,那

30個關於Shell指令碼的經典案例

本文目錄 11、iptables自動遮蔽訪問網站頻繁的IP 12、判斷使用者輸入的是否為IP地址 13、判斷使用者輸入的是否

30個關於Shell指令碼的經典案例

本文目錄 21、從FTP伺服器下載檔案 22、連續輸入5個100以內的數字,統計和、最小和最大 23、將結果分別賦值給變數

GAN網路入門教程GAN原理

在一篇部落格[GAN網路從入門教程(一)之GAN網路介紹](https://www.cnblogs.com/xiaohuiduan/p/13237486.html)中,簡單的對GAN網路進行了一些介紹,介紹了其是什麼,然後大概的流程是什麼。 在這篇部落格中,主要是介紹其數學公式,以及其演算法流程。當然數學公

NS2入門學習分裂物件模型和TclCL

 TclCL其實就是連線C++與Otcl,實現兩者的互相操作和兩者之間類的對應. NS中使用兩種語言原因: C++執行速度較快,是強制型別語言(進行嚴格的資料型別檢查),容易實現複雜的資料型別和精確/複雜的演算法。但是修改/debug和重新編譯時間較長,所以適合完成網路協

NS2入門學習Otcl知識點

面向物件的Tcl語言,物件和類的概念同C++類似。 1.類和物件的定義 % Class  Animal #定義類名 % Animal animal_1#產生類的物件 animal info class =>Animal

NS2入門學習Tcl知識點

1、基本命令格式換(如下總結一些易錯的知識點) “#”:註釋 ";"或者"換行"作為語句的結束 2、變數 變數不需要事先宣告; 在使用變數時要在變數名前加$,如$var; set  var 3,set命令用來給變數賦值;   unset var,u

Centos Docker 零開始2 mssql 的資料庫檔案儲存在主機

Docker mmsql新建資料庫如果能夠把資料庫檔案儲存在主機上就好了,centos好像可以掛載的 docker 的 run 命令: -v ~/nginx/www:/www :將主機中專案的目錄www掛載到容器的/www 準備命令一下: docker run -e

Asp.Net MVC4入門指南1入門介紹

前言 本教程將為您講解使用微軟的Visual Studio Express 2012或Visual Web Developer 2010 Express Service Pack 1 來建立一個ASP.NET MVC4 Web應用程式所需要的基礎知識。建議您使用Visual Studio 2012,你將不再