天天看點

把書讀薄-Shell入門基礎

運作

1、作為可執行程式

#!/bin/bash           # 指定解釋此腳本檔案的程式

$ chmod a+x test.sh   # 使腳本具有執行權限
$ ./text.sh           # 執行腳本

./test.sh             # 在目前目錄找
test.sh               # 去 PATH 裡尋找      

2、作為解釋器參數

$ bash test.sh      

變量

key="value"     # 定義變量, 變量名和等号之間不能有空格
readonly key    # 隻讀變量, 再次指派會報錯

echo $key     # 使用變量, 使用變量要在變量名前面加美元符号
echo ${key}   # 識别變量的邊界

unset key     # 删除變量      

變量類型

  1. 局部變量
  2. 環境變量
  3. shell變量

字元串

字元串可以用單引号,也可以用雙引号,也可以不用引号

單引号:原樣字元串,不可以有變量和轉義字元

雙引号:可以有變量和轉義字元

字元串拼接

name="Tom"

echo "hi "$name"!"  # hi Tom!
echo "hi ${name}!"  # hi Tom!
echo 'hi ${name}!'  # hi ${name}!      
echo ${#name}      # 字元長度 3
echo ${name:1:4}   # 字元串截取 om       

數組

Bash Shell隻支援一維數組, 下标由0開始

# 定義數組, "空格"分割
names=("Tom" "Jack")

ages=(
23
24
)

# 數組元素指派
names[2]="Jimi"

# 擷取數組元素
echo ${names[2]}  # Jimi

# 擷取數組所有元素
echo ${ages[@]}   # 23 24
echo ${ages[*]}   # 23 24

# 擷取數組的長度
echo ${#names[@]}  # 3      

注釋

# 單行注釋

:<<EOF
多行注釋
再寫一行
EOF      

傳遞參數

# $ ./1.sh 1 2 3 4

echo $#  # 參數個數 4
echo $*  # 顯示所有參數 1 2 3 4
echo $@  # 顯示所有參數 1 2 3 4

echo $0  # 檔案名 ./1.sh
echo $1  # 第一個參數 1
echo $2  # 第二個參數 2      

基本運算符

1、算術運算符

原生bash不支援數學運算,使用expr

+   加法      `expr $a + $b`  
-   減法      `expr $a - $b`
*   乘法      `expr $a \* $b`
/   除法      `expr $b / $a`
%   取餘      `expr $b % $a`
=   指派      a=$b
==  相等      [ $a == $b ]  注意空格
!=  不相等     [ $a != $b ] 

# 注意是反引号`, 需要空格
# MAC表達式  $(expr 1 + 1)        

2、關系運算符

關系運算符隻支援數字

-eq     相等equal             [ $a -eq $b ]
-ne     不相等not equal       [ $a -ne $b ]
-gt     大于greater than      [ $a -gt $b ] 
-lt     小于lower than        [ $a -lt $b ]
-ge     大于等于greater&equal  [ $a -ge $b ] 
-le     小于等于lower&equal    [ $a -le $b ]      

3、布爾運算符

!   非   [ ! false ]
-o  或   [ $a -lt 20 -o $b -gt 100 ]
-a  與   [ $a -lt 20 -a $b -gt 100 ]      

4、邏輯運算符

&&  AND [[ $a -lt 100 && $b -gt 100 ]]
||  OR  [[ $a -lt 100 || $b -gt 100 ]]

# [[ 防止腳本中的邏輯錯誤      

5、字元串運算符

=   相等  [ $a = $b ]
!=  不相等 [ $a != $b ]
-z  長度為0 [ -z $a ]
-n  長度為0    [ -n "$a" ]
$   不為空   [ $a ]       

6、檔案測試運算符

-b file 裝置檔案                   [ -b $file ]
-c file 字元裝置檔案               [ -c $file ]
-d file 目錄                      [ -d $file ]
-f file 普通檔案                   [ -f $file ]
-r file 可讀                      [ -r $file ]
-w file 可寫                      [ -w $file ]
-x file 可執行                     [ -x $file ]
-s file 檔案不為空(檔案大小大于0)    [ -s $file ]
-e file 存在                       [ -e $file ]      

綜合示例

#!/bin/bash

# 算術計算
echo `expr 1 + 1`  # 注意空格 2

# 數字比較
a=1; b=2

if [ $a == $b ]
then
    echo "a==b"
else
    echo "a!=b"
fi

# 關系比較
if [ $a -eq $b ]
then
    echo "a==b"
else
    echo "a!=b"
fi

# 布爾運算
if [ $a -eq $b -o $a -gt $b ]
then
    echo "a==b or a>b"
else
    echo "a!=b and a<b"
fi

# 邏輯運算
if [[ $a -eq $b || $a -gt $b ]]
then
    echo "a==b or a>b"
else
    echo "a!=b and a<b"
fi

# 字元串運算符
if [ $a ]
then 
    echo "a不為空"
else
    echo "a為空"
fi

# 檔案
if [ -f "1.sh" ]
then
    echo "是檔案"
else
    echo "不是檔案"
fi      

echo

echo "hello world"            # 普通字元串, 自動添加換行符
echo hello world              # 雙引号可以省略
echo "\"hello world\""        # 顯示轉義字元  "hello world"
echo -e "hello\n world"       # -e開啟轉義 \n換行
echo -e "hello world \c"      # -e開啟轉義 \c不換行
echo `date`                   # 顯示指令結果 Thu Jul 4 12:44:11 CST 2019

name="Tom"
echo ${name}                  # 輸出變量

echo "hi" > file.txt          # 結果重定向      

示例:讀取輸入并輸出

#!/bin/bash

read -p "請輸出使用者名:" content   # -p提示文字
read -p "請輸出密碼:" -s password  # -s 隐藏輸入内容
echo -e "\n使用者名: ${content}\n密碼: ${password}"

:<<EOF
$ ./1.sh
請輸出使用者名:Tom
請輸出密碼:
使用者名: Tom
密碼: 123
EOF      

printf 指令

示例

printf "%-10s |%10.4f\n" "小明" 2.3 # 不會自動添加換行符
# -表示左對齊,沒有則表示右對齊
# 10個字元寬的字元内
# 保留4位小數
      

格式化

d: Decimal 十進制整數
s: String 字元串
c: Char 字元
f: Float 浮點      

轉義字元

\c  不顯示換行字元
\n  換行
\r  回車(Carriage return)
\t  水準制表符
\v  垂直制表符
\\  一個字面上的反斜杠字元      

test測試

# 算數運算
echo $[1+1]  # 2

# 比較
a=1
b=1

if test $a -eq $b
then
    echo "a==b"
else
    echo "a!=b"
fi
# a==b      

流程控制

if

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi
      

for

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
      

while

while condition
do
    command
done      

until

until condition
do
    command
done      

case

case 值 in
模式1)    # 右圓括号分支
    command1
    ;;   # 兩個分号表示break
模式2)
    command2
    ;;
*)
    command3
    ;;
esac      

跳出循環

break和continue

read -p "輸入start 或者 stop: " user_command 

case $user_command in
"start")
    echo "start..."
    ;;
"stop")
    echo "stop..."
    ;;
*)
    echo "輸入不對啊"
    ;;
esac      

函數

# 定義函數,function可以加也可以省略, 不帶任何參數
function func(){
    echo "第一個參數 $1"  # $1擷取第一個參數
    echo "參數個數 $#"    # $#擷取參數個數
    echo "所有參數 $@"    # $@擷取所有參數
    return 0  # 函數傳回值(0-255)
}

# 調用函數,不加括号
func hi 你好
# 第一個參數 hi
# 參數個數 2
# 所有參數 hi 你好

echo $?   # 顯示最後指令的退出狀态
# 0      

輸入/輸出重定向

檔案描述符

0 通常是标準輸入(STDIN)

1 是标準輸出(STDOUT)

2 是标準錯誤輸出(STDERR)

command1 > file1          # 輸出重定向
command1 >> file1         # 追加輸出重定向
command 2 > file          # stderr重定向
command > file 2>&1       # 合并stdout和stderr
command1 < file1          # 輸入重定向
command > /dev/null 2>&1  # 屏蔽輸出      
$ echo -e 'hello world\nhi china' > text.txt

$ cat text.txt
hello world
hi china

$ wc -l < text.txt
       2
      

檔案包含

1.sh
#!/bin/bash

function func(){
    echo "hi"
    return 0
}
      
2.sh
#!/bin/bash

# . ./1.sh  # 使用.引入檔案, 注意空格

source ./1.sh  # 使用source引入檔案

func      

參考

Shell 教程-菜鳥教程