歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> SHELL編程 >> Shell編程入門總結(一)

Shell編程入門總結(一)

日期:2017/3/3 14:13:45   编辑:SHELL編程

本文的主要內容:1、編寫Shell腳本的一般步驟

2、在Shell腳本中輸出文本 3、Shell腳本中的變量

4、Shell腳本中的函數 5、流程控制:if 分支結構

6、Shell中讀取鍵盤輸入一、編寫Shell 腳本

一般步驟:1.編寫一個腳本 2.使腳本文件可執行 3.把腳本放置到 shell 能夠找到的地方例如:

1.編寫hello_world腳本

#!/bin/bash
# This is our first script.
echo 'Hello World!'
2.賦予可執行權限

chmod 700 hello_world
3.執行腳本

./hello_world
4.若想讓系統中的每個用戶都可以使用, 那麼可將腳本放到 /usr/local/bin,系統管理員使用的腳本經常放到 /usr/local/sbin 目錄下。

二、Shell中輸出文本使用echo方式

例如:

echo "a string"
使用"here document"方式(可以隨意的嵌入引號)

格式如下:

command << token

text

token

這裡的 command 是一個可以接受標准輸入的命令名,token 是一個用來指示嵌入文本結束的字符串

把操作符"<<"改為 "<<-",shell 會忽略開頭的 tab 字符,可使用縮進提高可讀性

例如:

cat << _EOF_
a string
_EOF_

cat <<- _EOF_
	a string
_EOF_
例子:使用 一個 here document 將一系列的命令傳遞到 ftp 程序中以從一個遠端 FTP 服務器中得到一個文件

#!/bin/bash
# Script to retrieve a file via FTP
FTP_SERVER=***
FTP_PATH=***
REMOTE_FILE=***
ftp -n << _EOF_
open $FTP_SERVER
user anonymous me@linuxbox
cd $FTP_PATH
hash
get $REMOTE_FILE
bye
_EOF_
ls -l $REMOTE_FILE
三、Shell腳本中的變量

創建變量或給變量賦值variable=value(注:等號左右不能有空格)

可以在同一行中對多個變量賦值a=5 b="a string"

使用變量$variable 或 ${variable}

例如

b="a string" 
c="a string and $b" 
mv $filename ${filename}1

四、Shell中的函數函數語法形式(其中name為函數名,commands為一系列包含在函數中的命令,函數中須至少包含一條命令,return為可選)

function name {

commands

return

}

name () {

commands

return

}

*例如

#!/bin/bash
function_1 () {
   echo "Function_1 executed."
  return
}
cat << _EOF_
$(function_1)
_EOF_
局部變量

*例如

funct_1 () {
    local foo  #funct_1中的局部變量
    foo=1
    echo "funct_1: foo = $foo"
}
五、流程控制:if 分支結構

if 語句語法如下if commands; then

commands

[elif commands; then

commands...]

[else

commands]

fi

*例如:

x=5
if [ $x = 5 ]; then
    echo "x equals 5."
else
    echo "x does not equal 5."
fi
退出狀態

當命令執行完畢後會給系統發送一個值,叫做退出狀態。Shell 提供了一個參數$?可用來檢查退出狀態

例如:(狀態0為命令執行成功)

$ ls -d /usr/bin

/usr/bin

$ echo $?

0

測試*經常與 if 一塊使用的命令是 test。test 命令執行各種各樣的檢查與比較,它有兩種等價模式:

test expression

[ expression ]

*其中expression 為一個表達式,其執行結果是 true 或者是 false。當表達式為真時,這個 test 命令返回一個0退出狀態,當表達式為假時,test 命令退出狀態為1

測試表達式*文件表達式

file1 -ef file2:file1 和 file2 擁有相同的索引號(通過硬鏈接兩個文件名指向相同的文件)

file1 -nt file2:file1新於 file2

file1 -ot file2:file1早於 file2

-b file:file 存在並且是一個塊(設備)文件

-c file:file 存在並且是一個字符(設備)文件

-d file:file 存在並且是一個目錄

-e file:file 存在

-f file:file 存在並且是一個普通文件

-g file:file 存在並且設置了組 ID

-G file:file 存在並且由有效組 ID 擁有

-k file:file 存在並且設置了它的“sticky bit”

-L file:file 存在並且是一個符號鏈接

-O file:file 存在並且由有效用戶 ID 擁有

-p file:file 存在並且是一個命名管道

-r file:file 存在並且可讀(有效用戶有可讀權限)

-s file:file 存在且其長度大於零

-S file:file 存在且是一個網絡 socket

-t fd:fd 是一個定向到終端/從終端定向的文件描述符 。 這可以被用來決定是否重定向了標准輸入/輸出錯誤

-u file:file 存在並且設置了 setuid 位

-w file:file 存在並且可寫(有效用戶擁有可寫權限)

-x file:file 存在並且可執行(有效用戶有執行/搜索權限)

*文件表達式例子(其中在表達式中參數$FILE兩邊的引號並不是必需的,但這可防范空參數)

test_file () {
    # test-file: Evaluate the status of a file
    FILE=~/.bashrc
    if [ -e "$FILE" ]; then
        if [ -f "$FILE" ]; then
            echo "$FILE is a regular file."
        fi
        if [ -d "$FILE" ]; then
            echo "$FILE is a directory."
        fi
        if [ -r "$FILE" ]; then
            echo "$FILE is readable."
        fi
        if [ -w "$FILE" ]; then
            echo "$FILE is writable."
        fi
        if [ -x "$FILE" ]; then
            echo "$FILE is executable/searchable."
        fi
    else
        echo "$FILE does not exist"
        return 1
    fi
}
*字符串表達式

string:string 不為 null

-n string:字符串 string 的長度大於零

-z string:字符串 string 的長度為零

string1 = string2或string1 == string2:string1 和 string2 相同. 單或雙等號都可以,不過雙等號更受歡迎

string1 != string2:string1 和 string2 不相同

string1 > string2:sting1 排列在 string2 之後

string1 < string2:string1 排列在 string2 之前

注:> 和 <表達式操作符必須用引號引起來或者是用反斜槓轉義,否則會被 shell 解釋為重定向操作符,造成潛在地破壞結果

*字符串表達式例子:

#!/bin/bash
# test-string: evaluate the value of a string
ANSWER=maybe
if [ -z "$ANSWER" ]; then
    echo "There is no answer." >&2
    exit 1
fi
if [ "$ANSWER" = "yes" ]; then
    echo "The answer is YES."
elif [ "$ANSWER" = "no" ]; then
    echo "The answer is NO."
elif [ "$ANSWER" = "maybe" ]; then
    echo "The answer is MAYBE."
else
    echo "The answer is UNKNOWN."
fi
*整型表達式

integer1 -eq integer2:integer1 等於 integer2

integer1 -ne integer2:integer1 不等於 integer2

integer1 -le integer2:integer1 小於或等於 integer2

integer1 -lt integer2:integer1 小於 integer2

integer1 -ge integer2:integer1 大於或等於 integer2

integer1 -gt integer2:integer1 大於 integer2

*整型表達式例子:

#!/bin/bash
# test-integer: evaluate the value of an integer.
INT=-5
if [ -z "$INT" ]; then
    echo "INT is empty." >&2
    exit 1
fi
if [ $INT -eq 0 ]; then
    echo "INT is zero."
else
    if [ $INT -lt 0 ]; then
        echo "INT is negative."
    else
        echo "INT is positive."
    fi
    if [ $((INT % 2)) -eq 0 ]; then
        echo "INT is even."
    else
        echo "INT is odd."
    fi
fi
更現代的測試版本

*目前的 bash 版本包含一個復合命令:[[ expression ]],與test相比增加了一個重要的新的字符串表達式:string1 =~ regex,若string1匹配擴展的正則表達式 regex則返回真

例子:

#!/bin/bash
# test-integer2: evaluate the value of an integer.
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
    if [ $INT -eq 0 ]; then
        echo "INT is zero."
    else
        if [ $INT -lt 0 ]; then
            echo "INT is negative."
        else
            echo "INT is positive."
        fi
        if [ $((INT % 2)) -eq 0 ]; then
            echo "INT is even."
        else
            echo "INT is odd."
        fi
    fi
else
    echo "INT is not an integer." >&2
    exit 1
fi
*為整數設計的復合命令:(( ))

例子:

#!/bin/bash
# test-integer2a: evaluate the value of an integer.
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
    if ((INT == 0)); then
        echo "INT is zero."
    else
        if ((INT < 0)); then
            echo "INT is negative."
        else
            echo "INT is positive."
        fi
        if (( ((INT % 2)) == 0)); then
            echo "INT is even."
        else
            echo "INT is odd."
        fi
    fi
else
    echo "INT is not an integer." >&2
    exit 1
fi
通過使用邏輯操作符來結合表達式

操作符測 試[[ ]] 和 (( ))AND-a&&OR-o||NOT!!控制操作符:分支的另一種方法*bash 支持兩種可以執行分支任務的控制操作符。這個 &&(AND)和||(OR)操作符作用如同復合命令[[ ]]中的邏輯操作符

*語法:command1 && command2 和 command1 || command2

*對於 && 操作符,只有當command1 執行成功後,才會執行 command2。對於 || 操作符,只有當command1 執行失敗後, 才會執行command2

*例如:

$ mkdir temp && cd temp :在成功創建目錄temp後跳轉到temp

$ [ -d temp ] || mkdir temp :若目錄 temp 不存在則創建這個目錄

[ -d temp ] || exit 1 : 若目錄temp不存在則返回退出狀態1

六、讀取鍵盤輸入(交互)read - 從標准輸入讀取單行數據

*語法形式:read [-options] [variable...]

*讀取一個整數:

echo -n "Please enter an integer -> "
read var
echo "var = '$var'"
*給多個變量賦值:

echo -n "Enter one or more values > "
read var1 var2
echo "var1 = '$var1'"
echo "var2 = '$var2'"
*若沒有提供變量名,shell 變量 REPLY 會包含數據行

echo -n "Enter one or more values > "
read
echo "REPLY = '$REPLY'"
*read選項

-a array:把輸入賦值到數組 array 中,從索引號零開始

-d delimiter:用字符串 delimiter 中的第一個字符指示輸入結束,而不是一個換行符

-e:使用 Readline 來處理輸入。這使得與命令行相同的方式編輯輸入

-n num:讀取 num 個輸入字符,而不是整行

-p prompt:為輸入顯示提示信息,使用字符串 prompt

-r:Raw mode. 不把反斜槓字符解釋為轉義字符

-s:Silent mode. 不會在屏幕上顯示輸入的字符。當輸入密碼和其它確認信息的時候,這會很有幫助

-t seconds:超時. 幾秒鐘後終止輸入。read 會返回一個非零退出狀態,若輸入超時

-u fd:使用文件描述符 fd 中的輸入,而不是標准輸入

*read選項例子:

#!/bin/bash
if read -t 10 -sp "Enter secret pass phrase > " secret_pass; then
    echo -e "\nSecret pass phrase = '$secret_pass'"
else
    echo -e "\nInput timed out" >&2
    exit 1
fi
*此腳本提示用戶輸入一個密碼,若在10秒內沒有完成輸入,則腳本會退出並返回一個錯誤。因包含了一個 -s 選項,所以輸入的密碼不會出現在屏幕上。校正輸入

*校正各種輸入的示例程序:

#!/bin/bash
invalid_input () {
    echo "Invalid input '$REPLY'" >&2
    exit 1
}
read -p "Enter a single item > "
# input is empty (invalid)
[[ -z $REPLY ]] && invalid_input
# input is multiple items (invalid)
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input
# is input a valid filename?
if [[ $REPLY =~ ^[-[:alnum:]\._]+$ ]]; then
    echo "'$REPLY' is a valid filename."
    if [[ -e $REPLY ]]; then
        echo "And file '$REPLY' exists."
    else
        echo "However, file '$REPLY' does not exist."
    fi
    # is input a floating point number?
    if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then
        echo "'$REPLY' is a floating point number."
    else
        echo "'$REPLY' is not a floating point number."
    fi
    # is input an integer?
    if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then
        echo "'$REPLY' is an integer."
    else
        echo "'$REPLY' is not an integer."
    fi
else
    echo "The string '$REPLY' is not a valid filename."
fi
菜單,一種常見的交互類型稱為菜單驅動

*菜單驅動例子

#!/bin/bash
# read-menu: a menu driven system information program
clear
echo "
Please Select:

    1. Display System Information
    2. Display Disk Space
    3. Display Home Space Utilization
    0. Quit
"
read -p "Enter selection [0-3] > "

if [[ $REPLY =~ ^[0-3]$ ]]; then
    if [[ $REPLY == 0 ]]; then
        echo "Program terminated."
        exit
    fi
    if [[ $REPLY == 1 ]]; then
        echo "Hostname: $HOSTNAME"
        uptime
        exit
    fi
    if [[ $REPLY == 2 ]]; then
        df -h
        exit
    fi
    if [[ $REPLY == 3 ]]; then
        if [[ $(id -u) -eq 0 ]]; then
            echo "Home Space Utilization (All Users)"
            du -sh /home/*
        else
            echo "Home Space Utilization ($USER)"
            du -sh $HOME
        fi
        exit
    fi
else
    echo "Invalid entry." >&2
    exit 1
fi
*從邏輯上講,這個腳本被分為兩部分。第一部分顯示菜單和用戶輸入。第二部分確認用戶反饋,並執行 選擇的行動參考:《The Linux Command Line》

Copyright © Linux教程網 All Rights Reserved