Shell基礎(chǔ)

一、構(gòu)建基本腳本

1.創(chuàng)建shell腳本文件

在創(chuàng)建shell腳本文件時,必須在文件的第一行指定要使用的shell,其格式為:

#!/bin/bash

在通常的shell腳本中,井號(#)用作注釋行,shell并不會處理shell腳本中的注釋行。然而,shell腳本文件的第一行是個例外,#后面的驚嘆號會告訴shell用哪個shell來運行腳本:

#!/bin/bash
# This script displays the date
date

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
2020年 09月 03日 星期四 23:37:55 CST

2.顯示消息

使用echo命令顯示字符串:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo hello shell
hello shell
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo "It's shell"
It's shell
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo 'It says "shell"'
It says "shell"

可以將echo語句添加到shell腳本中任何需要顯示額外信息的地方:

#!/bin/bash
# This script displays the date
echo "The time and date are:"
date
echo "end"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
The time and date are:
2020年 09月 03日 星期四 23:47:43 CST
end

如果想把文本字符串和命令輸出顯示在同一行中,可以用echo語句的-n參數(shù):

#!/bin/bash
# This script displays the date
echo -n "The time and date are:"
date
echo "end"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
The time and date are:2020年 09月 04日 星期五 00:07:34 CST
end

3.使用變量

環(huán)境變量

shell維護著一組環(huán)境變量,用來記錄特定的系統(tǒng)信息。比如系統(tǒng)的名稱、登錄到系統(tǒng)上的用戶名、用戶的系統(tǒng)ID(也稱為UID)、用戶的默認主目錄以及shell查找程序的搜索路徑??梢杂胹et命令來顯示一份完整的當前環(huán)境變量列表。在腳本中,你可以在環(huán)境變量名稱之前加上美元符($)來使用這些環(huán)境變量:

#!/bin/bash
echo "User info for userid: $USER"
echo UID: $UID
echo HOME: $HOME

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
User info for userid: zhangwenming
UID: 1009
HOME: /home/zhangwenming

要顯示美元符,必須在它前面放置一個反斜線:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo This cost \$99
This cost $99

用戶變量

除了環(huán)境變量,shell腳本還允許在腳本中定義和使用自己的變量。定義變量允許臨時存儲數(shù)據(jù)并在整個腳本中使用,從而使shell腳本看起來更像一個真正的計算機程序。與系統(tǒng)變量類似,用戶變量可通過美元符引用:

#!/bin/bash
days=10
guest="shell"
echo "$guest checked in $days days ago"
days=5
guest="python"
echo "$guest checked in $days days ago"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
shell checked in 10 days ago
python checked in 5 days ago

命令替換

shell腳本中最有用的特性之一就是可以從命令輸出中提取信息,并將其賦給變量,有兩種方法:

  • 反引號字符(`)
  • $( )格式
#!/bin/bash
testing1=`date`
testing2=$(date +%y%m%d)
echo "$testing1"
echo "$testing2"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
2020年 09月 04日 星期五 00:54:43 CST
200904

4.重定向輸入和輸出

輸出重定向

最基本的重定向?qū)⒚畹妮敵霭l(fā)送到一個文件中。bash shell用大于號(>)來完成這項功能:

#!/bin/bash
testing1=`date`
testing2=$(date +%y%m%d)
echo "$testing1"
echo "$testing2"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test > output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
2020年 09月 04日 星期五 02:10:53 CST
200904

有時你可能并不想覆蓋文件原有內(nèi)容,而是想要將命令的輸出追加到已有文件中,可以用雙大于號(>>)來追加數(shù)據(jù):

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test >> output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
2020年 09月 04日 星期五 02:12:35 CST
200904
2020年 09月 04日 星期五 02:13:46 CST
200904

輸入重定向

輸入重定向符號是小于號(<):

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
2020年 09月 04日 星期五 02:12:35 CST
200904
2020年 09月 04日 星期五 02:13:46 CST
200904
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ wc < output
  4  14 100

wc命令可以對數(shù)據(jù)中的文本進行計數(shù)。默認情況下,它會輸出3個值:

  • 文本的行數(shù)
  • 文本的詞數(shù)
  • 文本的字節(jié)數(shù)

5.管道

管道被放在命令之間,將一個命令的輸出重定向到另一個命令中:

command1 | command2

Linux系統(tǒng)實際上會同時運行這兩個命令,在系統(tǒng)內(nèi)部將它們連接起來。在第一個命令產(chǎn)生輸出的同時,輸出會被立即送給第二個命令。數(shù)據(jù)傳輸不會用到任何中間文件或緩沖區(qū):

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output | wc
      4      14     100

6.執(zhí)行數(shù)學(xué)運算

expr命令

expr命令允許在命令行上處理數(shù)學(xué)表達式,但是特別笨拙:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ expr 5 + 7
12

在shell腳本中使用expr命令:

#!/bin/bash
var1=10
var2=20
var3=$(expr $var2 / $var1)
echo The result is $var3

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
The result is 2

使用方括號

在bash中,在將一個數(shù)學(xué)運算結(jié)果賦給某個變量時,可以用美元符和方括號( $[ operation ] )將數(shù)學(xué)表達式圍起來:

#!/bin/bash
var1=10
var2=20
var3=$[($var2 / $var1) * 10]
echo The result is $var3

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
The result is 20

浮點解決方案

bash計算器實際上是一種編程語言,它允許在命令行中輸入浮點表達式,然后解釋并計算該表達式,最后返回結(jié)果:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
5 * 1.2
6.0

在腳本中使用bc,基本格式如下:

variable=$(echo "options; expression" | bc)
#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The result is $var1

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
The result is .6880

7.退出腳本

查看退出狀態(tài)碼

Linux提供了一個專門的變量$?來保存上個已執(zhí)行命令的退出狀態(tài)碼:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ date
2020年 09月 04日 星期五 04:06:55 CST
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo $?
0

exit命令

默認情況下,shell腳本會以腳本中的最后一個命令的退出狀態(tài)碼退出。exit命令允許你在腳本結(jié)束時指定一個退出狀態(tài)碼:

#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The result is $var1
exit 99

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
The result is .6880
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ echo $?
99

二、使用結(jié)構(gòu)化命令

1.使用if-then語句

最基本的結(jié)構(gòu)化命令就是if-then語句,格式如下:

if command
then 
    commands
fi

在其他編程語言中,if語句之后的對象是一個等式,這個等式的求值結(jié)果為TRUE或FALSE。但bash shell的if語句并不是這么做的。bash shell的if語句會運行if后面的那個命令,如果該命令的退出狀態(tài)碼是0(該命令成功運行),位于then部分的命令就會被執(zhí)行。如果該命令的退出狀態(tài)碼是其他值,then部分的命令就不會被執(zhí)行,bash shell會繼續(xù)執(zhí)行腳本中的下一個命令:

#!/bin/bash
if pwd
then
    echo "It worked"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
/home/zhangwenming/workspace/Tomorrow
It worked

2.if-then-else語句

if command
then 
    commands
else
    commands
fi

3.嵌套if

if command1
then 
    command set 1
elif command2
then
    command set 2
elif command3
then
    command set 3
fi

4.test命令

test命令提供了在if-then語句中測試不同條件的途徑。如果test命令中列出的條件成立,test命令就會退出并返回退出狀態(tài)碼0,這樣if-then語句就與其他編程語言中的if-then語句以類似的方式工作了。如果條件不成立,test命令就會退出并返回非零的退出狀態(tài)碼,這使得if-then語句不會再被執(zhí)行。test命令的格式非常簡單:

test condition

condition是test命令要測試的一系列參數(shù)和值。當用在if-then語句中時,test命令看起來是這樣的:

if test condition
then
    commands
fi

如果不寫test命令的condition部分,它會以非零的退出狀態(tài)碼退出,并執(zhí)行else語句塊:

#!/bin/bash
if test
then
    echo "It excute then"
else
    echo "It excute else"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
It excute else

可以使用test命令確定變量中是否有內(nèi)容:

#!/bin/bash
variable="Full"
if test variable
then
    echo "It excute then"
else
    echo "It excute else"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
It excute then

bash shell提供了另一種條件測試方法,無需在if-then語句中聲明test命令:

if [ condition ]
then
    commands
fi

方括號定義了測試條件。注意,第一個方括號之后和第二個方括號之前必須加上一個空格,否則就會報錯。

test命令可以判斷三類條件:

  • 數(shù)值比較
  • 字符串比較
  • 文件比較

數(shù)值比較

比較 描述
n1 -eq n2 檢查n1是否與n2相等
n1 -ge n2 檢查n1是否大于或等于n2
n1 -gt n2 檢查n1是否大于n2
n1 -le n2 檢查n1是否小于或等于n2
n1 -lt n2 檢查n1是否小于n2
n1 -ne n2 檢查n1是否不等于n2
#!/bin/bash
var1=10
var2=20
if [ $var1 -gt $var2 ]
then
    echo ">"
else
    echo "<="
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
<=

字符串比較

比較 描述
str1 = str2 檢查str1是否和str2相同
str1 != str2 檢查str1是否和str2不同
str1 < str2 檢查str1是否比str2小
str1 > str2 檢查str1是否比str2大
-n str1 檢查str1的長度是否非0
-z str1 檢查str1的長度是否為0
#!/bin/bash
var1=hello
var2=world
if [ $var1 \> $var2 ]
then
    echo ">"
else
    echo "<="
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test
<=

文件比較

文件比較是shell編程中最為強大、也是用得最多的比較形式,它允許你測試Linux文件系統(tǒng)上文件和目錄的狀態(tài)。

比較 描述
-d file 檢查file是否存在并是一個目錄
-e file 檢查file是否存在
-f file 檢查file是否存在并是一個文件
-r file 檢查file是否存在并可讀
-s file 檢查file是否存在并非空
-w file 檢查file是否存在并可寫
-x file 檢查file是否存在并可執(zhí)行
-O file 檢查file是否存在并屬當前用戶所有
-G file 檢查file是否存在并且默認組與當前用戶相同
file1 -nt file2 檢查file1是否比file2新
file1 -ot file2 檢查file1是否比file2舊
#!/bin/bash
var=/home/zhangwenming
if [ -d $var ]
then
    echo "directory"
else
    echo "not directory"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
directory

5.復(fù)合測試條件

if-then語句允許你使用布爾邏輯來組合測試,有兩種布爾運算符可用:

  • [ condition1 ] && [ condition2 ]
  • [ condition1 ] || [ condition2 ]
#!/bin/bash
var=/home/zhangwenming

if [ -d $var ] && [ -w $var ]
then
    echo "directory can write"
else
    echo "not directory or can not write"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
directory can write

6.if-then的高級特性

使用雙括號

雙括號命令的格式如下:

(( expression ))

expression可用是任意的數(shù)學(xué)賦值或比較表達式。除了test命令使用的標準數(shù)學(xué)運算符,還會用到其他運算符:

符號 描述
val++ 后增
val-- 后減
++val 先增
--val 先減
! 邏輯求反
~ 位求反
** 冪運算
<< 左位移
>> 右位移
& 位布爾和
| 位布爾或
&& 邏輯和
|| 邏輯或
#!/bin/bash
var1=10

if (( $var1 ** 2 > 90 ))
then
    (( var2 = var1 ** 2 ))
    echo "result is: $var2"
else
    (( var2 = var1 * 2 ))
    echo "result is: $var2"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
result is: 100

注意,不需要將雙括號中表達式里大于號轉(zhuǎn)義。這是雙括號命令提供的另一個高級特性。

使用雙方括號

雙方括號命令的格式如下:

[[ expression ]]

雙方括號里的expression使用了test命令中采用的標準字符串比較。但它提供了test命令未提供的另一個特性——模式匹配。在模式匹配中,可以定義一個正則表達式來匹配字符串值:

#!/bin/bash
if [[ $USER == zhang* ]]
then
    echo "hello $USER"
else
    echo "Sorry, I do not know you"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
hello zhangwenming

7.case命令

case命令采用列表格式來檢查單個變量的多個值:

case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac

case命令會將指定的變量與不同模式進行比較。如果變量和模式是匹配的,那么shell會執(zhí)行為該模式指定的命令:

#!/bin/bash
case $USER in
li*)
  echo "Welcome, li";;
huang* | zhang*)
  echo "Welcome, huang or zhang";;
*)
  echo "Sorry, you are not allowed here";;
esac

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Welcome, huang or zhang

三、更多的結(jié)構(gòu)化命令

1.for命令

bash shell中for命令的基本格式:

for var in list
do 
    commands
done

讀取列表中的值:

#!/bin/bash
for test in Android Java Kotin Python 
do
  echo "current is: $test"
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
current is: Android
current is: Java
current is: Kotin
current is: Python

讀取列表中的復(fù)雜值:

#!/bin/bash
for test in I don\'t know if "this'll" work
do
  echo "current is: $test"
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
current is: I
current is: don't
current is: know
current is: if
current is: this'll
current is: work

從變量讀取列表:

#!/bin/bash
list="Android Java Kotin Python"
for test in $list "Shell"
do
  echo "current is: $test"
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
current is: Android
current is: Java
current is: Kotin
current is: Python
current is: Shell

從命令讀取值:

#!/bin/bash
file="output"
for test in $(cat $file)
do
  echo "current is: $test"
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
current is: 123
current is: 456
current is: abc

更改字段分隔符:

默認情況下,bash shell會將下列字符當做字段分隔符:

  • 空格
  • 制表符
  • 換行符

如果bash shell在數(shù)據(jù)中看到了這些字符中的任意一個,它就會假定這表明了列表中一個新數(shù)據(jù)字段的開始??梢栽趕hell腳本中臨時更改IFS環(huán)境變量的值來限制被bash shell當作字段分隔符的字符。例如,修改IFS的值,使其只能識別換行符:

#!/bin/bash
file="output"
IFS=$'\n'
for test in $(cat $file)
do
  echo "current is: $test"
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
current is: 123 456
current is: abc

如果要指定多個IFS字符,只要將它們在賦值行串起來就行:

IFS=$'\n':;" 

這個賦值會將換行符、冒號、分號和雙引號作為字段分隔符。

用通配符讀取目錄:

#!/bin/bash
file="output"
IFS=$'\n'
for file in /home/zhangwenming/workspace/Tomorrow/NEW_ZWM/*
do
    if [ -d "$file" ]
    then
      echo "$file is a directory"
    elif [ -f "$file" ]
    then
      echo "$file is a file"
    fi  
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
/home/zhangwenming/workspace/Tomorrow/NEW_ZWM/test_one is a file
/home/zhangwenming/workspace/Tomorrow/NEW_ZWM/test_two is a file
/home/zhangwenming/workspace/Tomorrow/NEW_ZWM/test.txt is a file

在Linux中,目錄名和文件名中包含空格當然是合法的。要適應(yīng)這種情況,應(yīng)該將$file變量用雙引號圈起來。

2.C語言風(fēng)格的for命令

#!/bin/bash
for (( a=1, b=10; a<=10; a++, b--))
do
    echo "$a - $b"
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
1 - 10
2 - 9
3 - 8
4 - 7
5 - 6
6 - 5
7 - 4
8 - 3
9 - 2
10 - 1

3.while命令

while的基本格式

while test command
do
    other commands
done

while命令中定義的test command和if-then語句中的格式一模一樣??梢允褂萌魏纹胀ǖ腷ash shell命令,或者用任何普通的bash shell命令,或者用test命令進行條件測試,比如測試變量值:

#!/bin/bash
var1=5
while [ $var1 -gt 0 ]
do
    echo $var1
    var1=$[ $var1 - 1 ]
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
5
4
3
2
1

使用多個測試命令

while命令允許你在while語句行定義多個測試命令。只有最后一個測試命令的退出狀態(tài)碼會被用來決定什么時候結(jié)束循環(huán):

#!/bin/bash
var1=5
while echo $var1
      [ $var1 -gt 0 ]
do
    echo "This is inside the loop"
    var1=$[ $var1 - 1 ]
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
5
This is inside the loop
4
This is inside the loop
3
This is inside the loop
2
This is inside the loop
1
This is inside the loop
0

4.until命令

until命令要求你指定一個通常返回非零退出狀態(tài)碼的測試命令。只有測試命令的退出狀態(tài)碼不為0,bash shell才會執(zhí)行循環(huán)中列出的命令。一旦測試命令返回了退出狀態(tài)碼0,循環(huán)就結(jié)束。until命令的格式如下:

until test command
do 
    other commands
done
#!/bin/bash
var1=5
until [ $var1 -le 0 ]
do
    echo "current is: $var1"
    var1=$[ $var1 - 1 ]
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
current is: 5
current is: 4
current is: 3
current is: 2
current is: 1

和while命令類似,你可以在until命令語句中放入多個測試條件,只有最后一個命令的退出狀態(tài)碼決定了bash shell是否執(zhí)行已定義的other commands:

#!/bin/bash
var1=5
until echo $var1
      [ $var1 -le 0 ]
do
    echo "inside the loop"
    var1=$[ $var1 - 1 ]
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
5
inside the loop
4
inside the loop
3
inside the loop
2
inside the loop
1
inside the loop
0

5.嵌套循環(huán)

#!/bin/bash
for (( a=1; a<=3; a++ ))
do
    echo "start loop $a:"
    for (( b=1; b<=3; b++ ))
    do
        echo "  inside the loop $b"
    done
done 

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
start loop 1:
  inside the loop 1
  inside the loop 2
  inside the loop 3
start loop 2:
  inside the loop 1
  inside the loop 2
  inside the loop 3
start loop 3:
  inside the loop 1
  inside the loop 2
  inside the loop 3

6.循環(huán)處理文件數(shù)據(jù)

#!/bin/bash
IFS=$'\n'
for entry in $(cat output)
do
    echo "value is $entry"
done

abczhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
value is 123 456
value is abc

7.控制循環(huán)

break命令

跳出單個循環(huán):

#!/bin/bash
for (( a=1; a<=3; a++ ))
do
    echo "current is $a"
    if [ $a -eq 2 ]
    then
        break
    fi
done 

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
current is 1
current is 2

跳出內(nèi)部循環(huán):

#!/bin/bash
for (( a=1; a<=3; a++ ))
do
    echo "start loop $a:"
    for (( b=1; b<=3; b++ ))
    do
        echo "  inside the loop $b"
        if [ $b -eq 2 ]
        then
            break
        fi
    done
done 

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
start loop 1:
  inside the loop 1
  inside the loop 2
start loop 2:
  inside the loop 1
  inside the loop 2
start loop 3:
  inside the loop 1
  inside the loop 2

跳出外部循環(huán):

break命令接受單個命令行參數(shù)值:break n,其中n指定了要跳出的循環(huán)層級,n為1表明跳出的是當前的循環(huán),n為2表明會停止下一級的外部循環(huán):

#!/bin/bash
for (( a=1; a<=3; a++ ))
do
    echo "start loop $a:"
    for (( b=1; b<=3; b++ ))
    do
        echo "  inside the loop $b"
        if [ $b -eq 2 ]
        then
            break 2
        fi
    done
done 

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
start loop 1:
  inside the loop 1
  inside the loop 2

continue命令

continue命令可以提前中止某次循環(huán)中的命令,但并不會完全終止整個循環(huán):

#!/bin/bash
for (( a=1; a<=3; a++ ))
do
    echo "start loop $a:"
    for (( b=1; b<=3; b++ ))
    do
        if [ $b -eq 2 ]
        then
            continue
        fi
        echo "  inside the loop $b"
    done
done 

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
start loop 1:
  inside the loop 1
  inside the loop 3
start loop 2:
  inside the loop 1
  inside the loop 3
start loop 3:
  inside the loop 1
  inside the loop 3

8.處理循環(huán)的輸出

在shell腳本中,你可以對循環(huán)的輸出使用管道或進行重定向,這可以通過在done命令之后添加一個處理命令來實現(xiàn):

#!/bin/bash
for (( a=1; a<=3; a++ ))
do
    echo "start loop $a:"
    for (( b=1; b<=3; b++ ))
    do
        if [ $b -eq 2 ]
        then
            continue
        fi
        echo "  inside the loop $b"
    done
done > output

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
start loop 1:
  inside the loop 1
  inside the loop 3
start loop 2:
  inside the loop 1
  inside the loop 3
start loop 3:
  inside the loop 1
  inside the loop 3

四、處理用戶輸入

1.命令行參數(shù)

向shell腳本傳遞數(shù)據(jù)的最基本方法是使用命令行參數(shù)。命令行參數(shù)允許在運行腳本時向命令行添加數(shù)據(jù)。bash shell會將一些稱為位置參數(shù)的特殊變量分配給輸入到命令行中的所有參數(shù),這也包括shell所執(zhí)行的腳本名稱。位置參數(shù)是標準的數(shù)字:0是程序名,1是第一個參數(shù),$2是第二個參數(shù),以此類推。

#!/bin/bash
echo "position 0: $0"
echo "position 1: $1"
echo "position 2: $2"
echo "position 3: $3"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell perfect
position 0: ./test.sh
position 1: hello
position 2: shell
position 3: perfect

在使用參數(shù)前一定要檢查其中是否存在數(shù)據(jù):

#!/bin/bash
echo "position 0: $0"
echo "position 1: $1"
echo "position 2: $2"
if [ -n "$s2" ]
then
  echo "position 3: $3"
else
  echo "position 3 no value"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell
position 0: ./test.sh
position 1: hello
position 2: shell
position 3 no value

2.特殊參數(shù)變量

參數(shù)統(tǒng)計

特殊變量$#含有腳本運行時攜帶的命令行參數(shù)的個數(shù),可以在腳本中任何地方使用這個特殊變量,就跟普通變量一樣:

#!/bin/bash
echo "position 0: $0"
echo "position 1: $1"
echo "position 2: $2"
if [ -n "$s2" ]
then
  echo "position 3: $3"
else
  echo "position 3 no value"
fi
echo "total param count: $#"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell
position 0: ./test.sh
position 1: hello
position 2: shell
position 3 no value
total param count: 2

抓取所有的數(shù)據(jù)

*和@變量可以用來輕松訪問所有參數(shù),這個兩個變量包含了命令行中出現(xiàn)的每一參數(shù)值。

*變量會將命令行上提供的所有參數(shù)當做一個單詞保存。@變量會將命令行上提供的所有參數(shù)當作同一字符串中的多個獨立的單詞,這樣你就能夠遍歷所有的參數(shù)值,得到每一個參數(shù),通常通過for命令完成。

#!/bin/bash
for param in "$*"
do
    echo "* is: $param"
done
for param in "$@"
do
    echo "@ is: $param"
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh hello shell
* is: hello shell
@ is: hello
@ is: shell

3.獲得用戶輸入

基本的讀取

read命令從標準輸入(鍵盤)或另一個文件描述符中接受輸入。在收到輸入后,read命令會將數(shù)據(jù)放進一個變量:

#!/bin/bash
echo -n "Enter you name: "
read name
echo "Hello $name, welcome to my program."

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Enter you name: Tomy
Hello Tomy, welcome to my program.

read命令包含了-p選項,允許你直接在read命令行指定提示符:

#!/bin/bash
read -p "Please enter your age: " age
days=$[ $age * 365 ]
echo "That makes you over $days days old"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Please enter your age: 10
That makes you over 3650 days old

使用多個變量:

#!/bin/bash
read -p "Please enter your name and age: " name age
days=$[ $age * 365 ]
echo "$name, you over $days days old"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Please enter your name and age: Android 11
Android, you over 4015 days old

超時

可以用-t選項來指定一個計時器,-t選項指定了read命令等待輸入的秒數(shù)。當計時器過期后,read命令會返回一個非零退出狀態(tài)碼:

#!/bin/bash
if read -t 5 -p "Please enter your name and age: " name age
then
    days=$[ $age * 365 ]
    echo "$name, you over $days days old"
else
    echo
    echo "Sorry, too slow"
fi

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Please enter your name and age:
Sorry, too slow

也可以不對輸入過程計時,而是讓read命令來統(tǒng)計輸入的字符數(shù),當輸入的字符達到預(yù)設(shè)的字符數(shù)時,就自動退出,將輸入的數(shù)據(jù)賦給變量:

#!/bin/bash
read -n1 -p "Do you want to continue [Y/N]? " answer
case $answer in
Y | y) echo
       echo "fine, continue on...";;
N | n) echo
       echo "OK, goodbye"
       exit;;
esac
echo "script end"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Do you want to continue [Y/N]? n
OK, goodbye

隱藏方式讀取

-s選項可以避免在read命令中輸入的數(shù)據(jù)出現(xiàn)在顯示器上(實際上,數(shù)據(jù)會被顯示,只是read命令會將文本顏色設(shè)成跟背景色一樣):

#!/bin/bash
read -s -p "Enter you password: " pass
echo
echo "your password is: $pass"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Enter you password:
your password is: tomorrow

從文件中讀取

也可以用read命令來讀取Linux系統(tǒng)上文件里保存的數(shù)據(jù)。每次調(diào)用read命令,它都會從文件中讀取一行文本。當文件中在沒有內(nèi)容時,read命令會退出并返回非零退出狀態(tài)碼:

#!/bin/bash
count=1
cat output | while read line
do 
    echo "Line $count: $line"
    count=$[$count + 1]
done
echo "read file done"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Line 1: start loop 1:
Line 2: inside the loop 1
Line 3: inside the loop 3
Line 4: start loop 2:
Line 5: inside the loop 1
Line 6: inside the loop 3
Line 7: start loop 3:
Line 8: inside the loop 1
Line 9: inside the loop 3
read file done

五、呈現(xiàn)數(shù)據(jù)

1.理解輸入和輸出

標準文件描述符

Linux系統(tǒng)將每個對象當作文件處理。這包括輸入和輸出進程。Linux用文件描述符(file descriptor)來標識每個文件對象。文件描述符是一個非負整數(shù),可以唯一標識會話中打開的文件。每個進程一次最多可以有幾個文件描述符。出于特殊目的,bash shell保留了前三個文件描述符(0、1和2):

文件描述符 縮寫 描述
0 STDIN 標準輸入
1 STDOUT 標準輸出
2 STDERR 標準錯誤

STDIN文件描述符代表shell的標準輸入。對終端界面來說,標準輸入是鍵盤。shell從STDIN文件描述符對應(yīng)的鍵盤獲得輸入,在用戶輸入時處理每個字符。在使用輸入重定向符號(<)時,Linux會用重定向指定的文件來替換標準輸入文件描述符。它會讀取文件并提取數(shù)據(jù),就如同它是鍵盤上鍵入的。

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat
Hello shell
Hello shell
^C
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat < output
start loop 1:
  inside the loop 1
  inside the loop 3
start loop 2:
  inside the loop 1
  inside the loop 3
start loop 3:
  inside the loop 1
  inside the loop 3

STDOUT文件描述符代表shell的標準輸出。在終端界面上,標準輸出就是終端顯示器。shell的所有輸出(包括shell中運行的程序和腳本)會被定向到標準輸出中,也就是顯示器。通過輸出重定向符號,通常會顯示到顯示器的所有輸出會被shell重定向到指定的重定向文件。你也可以將數(shù)據(jù)追加到某個文件,這可以用>>符號來完成。

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ date
2020年 09月 04日 星期五 21:32:27 CST
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ date >> output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
start loop 1:
  inside the loop 1
  inside the loop 3
start loop 2:
  inside the loop 1
  inside the loop 3
start loop 3:
  inside the loop 1
  inside the loop 3
2020年 09月 04日 星期五 21:32:47 CST

shell通過特殊的STDERR文件描述符來處理錯誤消息。STDERR文件描述符代表shell的標準錯誤輸出。shell或shell中運行的程序和腳本出錯時生成的錯誤消息都會發(fā)送到這個位置。默認情況下,STDERR文件描述符會和STDOUT文件描述符指向同樣的地方(盡管分配給它們的文件描述符值不同)。也就是說,默認情況下,錯誤消息也會輸出到顯示器輸出中。

重定向錯誤

只重定向錯誤:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ls -al badfile 2> output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
ls: cannot access badfile: No such file or directory

重定向錯誤和數(shù)據(jù):

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ls -al newfile badfile 2> errout 1> output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat errout
ls: cannot access badfile: No such file or directory
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
-rw-rw-r-- 1 zhangwenming zhangwenming 0  9月  3 23:02 newfile

將STDERR和STDOUT的輸出重定向到同一個輸出文件:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ls -al newfile badfile &> output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
ls: cannot access badfile: No such file or directory
-rw-rw-r-- 1 zhangwenming zhangwenming 0  9月  3 23:02 newfile

2.在腳本中重定向輸出

臨時重定向

可以將單獨的一行輸出重定向到STDERR:

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

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh 2> errout
This is normal output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat errout
This is error output

永久重定向

可以用exec命令告訴shell在腳本執(zhí)行期間重定向某個特定文件描述符:

#!/bin/bash
exec 2> errout
echo "hello shell"
exec 1>output
echo "this is normal output"
echo "this is err output" >&2

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
hello shell
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat output
this is normal output
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ cat errout
this is err output

3.在腳本中重定向輸入

exec命令允許你將STDIN重定向到Linux系統(tǒng)上的文件中:

#!/bin/bash
exec 0< output
count=1
while read line
do
    echo "Line #$count: $line"
    count=$[ $count + 1 ]
done

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Line #1: 123 456
Line #2: abc

六、控制腳本

1.處理信號

Linux利用信號與運行在系統(tǒng)中的進程進行通信。

生成信號

中斷進程:CTRL+C組合鍵會發(fā)送SIGINT信號,停止shell中當前運行的進程。

暫停進程:CTRL+Z組合鍵會生成一個SIGTSTP信號,停止shell中運行的任何進程。

停止進程跟終止進程不同:停止進程會讓程序繼續(xù)保留在內(nèi)存中,并能從上次停止的位置繼續(xù)運行。

捕獲信號

trap命令允許你來指定shell腳本要監(jiān)看并從shell中攔截的Linux信號。如果腳本收到了trap命令中列出的信號,該信號不再由shell處理,而是交由本地處理。trap命令的格式是:

trap commands signals
#!/bin/bash
trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT
sleep 10
echo "end of the script"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
^C Sorry! I have trapped Ctrl-C
end of the script

捕獲腳本退出

#!/bin/bash
trap "echo Goodbye..." EXIT
sleep 10
echo "end of script"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
end of script
Goodbye...

2.以后臺模式運行腳本

后臺運行腳本

#!/bin/bash
trap "echo Goodbye..." EXIT
sleep 10
echo "end of script"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
[1] 114907
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
0 S  1009 114907 114866  0  80   0 -  4158 wait   pts/13   00:00:00 test.sh
0 S  1009 114908 114907  0  80   0 -  2851 hrtime pts/13   00:00:00 sleep
0 R  1009 114909 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ end of script
Goodbye...

[1]+  Done                    ./test.sh
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
0 R  1009 114911 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps

運行多個后臺作業(yè)

#!/bin/bash
trap "echo Goodbye..." EXIT
sleep 10
echo "end of script"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
[1] 114919
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
[2] 114921
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
0 S  1009 114919 114866  0  80   0 -  4158 wait   pts/13   00:00:00 test.sh
0 S  1009 114920 114919  0  80   0 -  2851 hrtime pts/13   00:00:00 sleep
0 S  1009 114921 114866  0  80   0 -  4158 wait   pts/13   00:00:00 test.sh
0 S  1009 114922 114921  0  80   0 -  2851 hrtime pts/13   00:00:00 sleep
0 R  1009 114924 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ end of script
Goodbye...
end of script
Goodbye...

[1]-  Done                    ./test.sh
[2]+  Done                    ./test.sh
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1009 114866 114819  0  80   0 -  6799 wait   pts/13   00:00:00 bash
0 R  1009 114925 114866  0  80   0 -  3557 -      pts/13   00:00:00 ps

3.作業(yè)控制

查看作業(yè)

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh &
[1] 114941
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ jobs -l
[1]+ 114941 Running                 ./test.sh &
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ kill 114941
Goodbye...
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ jobs -l
[1]+ 114941 Terminated              ./test.sh

重啟停止的作業(yè)

要以后臺模式重啟一個作業(yè),可用bg命令加上作業(yè)號:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
^Z
[1]+  Stopped                 ./test.sh
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ bg 1
[1]+ ./test.sh &
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ end of script
Goodbye...

[1]+  Done                    ./test.sh

要以前臺模式重啟作業(yè),可用帶有作業(yè)號的fg命令:

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
^Z
[1]+  Stopped                 ./test.sh
zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ fg 1
./test.sh
end of script
Goodbye...

七、創(chuàng)建函數(shù)

1.基本的腳本函數(shù)

創(chuàng)建函數(shù)

有兩種格式可用用來在bash shell腳本中創(chuàng)建函數(shù)。第一種格式采用關(guān)鍵字function,后跟分配給該代碼塊的函數(shù)名:

function name {
    commands
}

第二種格式更接近于其他編程語言中定義函數(shù)的方式:

name() {
commands
}

使用函數(shù)

#!/bin/bash

function func1 {
  echo "This is an example of a function"
}

echo "call function start"
func1
func1
echo "call function end"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
call function start
This is an example of a function
This is an example of a function
call function end

2.返回值

默認退出狀態(tài)碼

默認情況下,函數(shù)的退出狀態(tài)碼是函數(shù)中最后一條命令返回的退出狀態(tài)碼。在函數(shù)執(zhí)行結(jié)束后,可以用標準變量$?來確定函數(shù)的退出狀態(tài)碼:

#!/bin/bash

function func1 {
  echo "This is an example of a function"
}

echo "call function start"
func1
echo "The exit status is: $?"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
call function start
This is an example of a function
The exit status is: 0

使用return命令

bash shell使用return命令來退出函數(shù)并返回特定的退出狀態(tài)碼。return命令允許指定一個整數(shù)值來定義函數(shù)的退出狀態(tài)碼,從而提供了一種簡單的途徑來編程設(shè)定函數(shù)的特定退出狀態(tài)碼:

#!/bin/bash

function func1 {
  echo "This is an example of a function"
  return 99
}

echo "call function start"
func1
echo "The exit status is: $?"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
call function start
This is an example of a function
The exit status is: 99

使用函數(shù)輸出

獲取任何類型的函數(shù)輸出,并將其保存到變量中:

#!/bin/bash

function func1 {
  echo "This is an example of a function"
}

result=$(func1)
echo "The exit status is: $result"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
The exit status is: This is an example of a function

3.在函數(shù)中使用變量

向函數(shù)傳遞參數(shù)

#!/bin/bash

function func1 {
  echo "param1 is $1"
  echo "param2 is $2"
}

func1 hello shell

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
param1 is hello
param2 is shell

在函數(shù)中處理變量

全局變量:默認情況下,你在腳本中定義的任何變量都是全局變量。在函數(shù)外定義的變量可以函數(shù)內(nèi)正常訪問。

#!/bin/bash

function func1 {
  value=$[ $value * 2 ]
}

value=99
func1
echo "result is: $value"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
result is: 198

局部變量:函數(shù)內(nèi)部使用的任何變量都可以被聲明成局部變量。

#!/bin/bash

function func1 {
  local temp=$[ $value * 2 ]
  value=$[ $temp + 100 ]
}

value=99
func1
echo "result is: $value"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
result is: 298

4.數(shù)組變量和函數(shù)

向函數(shù)傳遞數(shù)組參數(shù)

#!/bin/bash

function func1 {
  local sum=0
  local newarray
  newarray=($(echo "$@"))
  for value in ${newarray[*]}
  do
    sum=$[ $sum + $value ]
  done
    echo $sum
}

myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=$(func1 $arg1)
echo "result is: $result"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
The original array is: 1 2 3 4 5
result is: 15

從函數(shù)返回數(shù)組

#!/bin/bash

function func1 {
  local newarray
  newarray=($(echo "$@"))
  elements=$[ $# - 1 ]
  for (( i=0; i<=$elements; i++ ))
  {
    newarray[$i]=$[ ${newarray[$i]} * 2 ]
  }
  echo ${newarray[*]}
}

myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=($(func1 $arg1))
echo "The original array is: ${result[*]}"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
The original array is: 1 2 3 4 5
The original array is: 2 4 6 8 10

5.函數(shù)遞歸

#!/bin/bash

function factorial {
    if [ $1 -eq 1 ]
    then
        echo 1
    else 
        local temp=$[ $1 - 1 ]
        local result=$(factorial $temp)
        echo $[ $result * $1 ]
    fi
}

read -p "Enter value: " value
result=$(factorial $value)
echo "The factorial of $value is: $result"

zhangwenming@ubuntu61-PowerEdge-R730:~/workspace/Tomorrow$ ./test.sh
Enter value: 5
The factorial of 5 is: 120
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容