內容列表
1. 使用多個命令
方式 | 樣式 | 介紹 |
---|---|---|
使用; 連接兩條命令 |
command1 ; command2 | 第一條失敗後,第二條仍然會 執行 |
使用&& 連接兩條命令 |
command1 && command2 | 第一條失敗後,第二條不會 執行 |
# 1. 使用;分隔兩個命令
[root@vm14 ~]# date ; pwd
2020年 03月 29日 星期日 21:18:41 CST
/root
# 使用;進行分隔的命令,當第一條失敗後,第二條仍然會執行
[root@vm14 ~]# date %m ; pwd
date: 無效的日期"%m"
/root
# 2. 使用&&連接
[root@vm14 ~]# date && pwd
2020年 03月 29日 星期日 21:20:31 CST
/root
# 使用&&連接的兩條命令,第一條失敗後,第二條不會繼續執行
[root@vm14 ~]# date %m && pwd
date: 無效的日期"%m"
2. 創建腳本文件
shell腳本第一行內容格式爲:#!/bin/bash
,用於指定執行腳本所使用的的shell(shell有多種,此處指定使用bash執行)。當然第一行內容可以缺失
,執行時會使用用戶的默認shell執行。
我們通過vim創建第一個測試腳本/root/shell/test1.sh
,內容如下:
#!/bin/bash
# 這一行是註釋內容,shell中以#開頭的都是註釋(不包括第一行shell類型聲明)
date
pwd
在目錄/root/shell
下腳本執行:
# 方式1,使用sh進行執行
[root@vm14 shell]# sh test1.sh
2020年 03月 29日 星期日 21:36:40 CST
/root/shell
# 方式2,使用相對路徑進行執行
[root@vm14 shell]# chmod u+x test1.sh
[root@vm14 shell]# ./test1.sh
2020年 03月 29日 星期日 21:40:02 CST
/root/shell
# 方式3,將/root/shell配置到PATH中,然後使用文件名進行調用
# 3.1 將/root/shell加入PATH
cat >> ~/.bash_profile << EOF
PATH=\$PATH:/root/shell
export PATH
EOF
# 3.2 使PATH生效
[root@vm14 shell]# source ~/.bash_profile
# 3.3 查看PATH,如果輸出內容包含/root/shell則說明設置成功
[root@vm14 shell]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/shell
# 3.4 執行shell(需要進行權限修改)
[root@vm14 shell]# test1.sh
2020年 03月 29日 星期日 21:50:17 CST
/root/shell
# 方式4,一般情況下~/bin已經被加入到PATH中,也就是我們只需要在~(用戶home)下創建bin目錄,然後在bin下創建shell腳本便可直接執行
3. 顯示消息
# 使用echo將信息顯示到控制檯,字符串無需用引號(’|")進行標示
[root@vm14 shell]# echo this is a test message
this is a test message
# 當內容有單引號時,用雙引號標示字符串
[root@vm14 shell]# echo "this's a ' message"
this's a ' message
# 當內容有雙引號時,用單引號標示字符串
[root@vm14 shell]# echo 'this is a "" message'
this is a "" message
# 同時包含時
[root@vm14 shell]# echo "this'"'s a " message'
this's a " message
創建腳本/root/shell/test2.sh
,內容如下
#!/bin/bash
# 輸出當前時間
echo '當前時間是:'
date
腳本執行:
# 在/root/shell下執行
[root@vm14 shell]# sh test2.sh
當前時間是:
2020年 03月 29日 星期日 22:08:00 CST
# 上面的輸出中描述與時間不在一行,可以將腳本中echo命令第一個參數改成-n使其輸出到一行
# echo -n '當前時間是:'
[root@vm14 shell]# sh test2.sh
當前時間是:2020年 03月 29日 星期日 22:10:59 CST
4. 使用變量
4.1 環境變量
shell維護着一組環境變量,用來記錄特定的系統信息。比如系統的名稱、登錄到系統上的用
戶名、用戶的系統ID(也稱爲UID)、用戶的默認主目錄以及shell查找程序的搜索路徑。可以用
set命令來顯示一份完整的當前環境變量列表。
[root@vm14 shell]# set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
# 省略
USER=root
XDG_RUNTIME_DIR=/run/user/0
XDG_SESSION_ID=17
_=test2.sh
colors=/root/.dir_colors
獲取系統變量
# 顯示用戶名
[root@vm14 shell]# echo 用戶名:$USER
用戶名:root
# 顯示home
[root@vm14 shell]# echo home:$HOME
home:/root
# 轉義字符使用,使用\可以使$不再解讀爲取變量值
[root@vm14 shell]# echo 商品價格:$15
商品價格:5
[root@vm14 shell]# echo 商品價格:\$15
商品價格:$15
4.2 用戶變量
# 定義變量
[root@vm14 shell]# var1=第一個變量
[root@vm14 shell]# var2=第二個變量
[root@vm14 shell]# echo $var1
第一個變量
[root@vm14 shell]# echo $var1 $var2
第一個變量 第二個變量
4.3 命令替換
命令替換:將命令執行結果賦值給變量
# 方式1,使用`符號
[root@vm14 shell]# var1=`date`
[root@vm14 shell]# echo $var1
2020年 03月 29日 星期日 22:25:46 CST
# 方式2,使用$()
[root@vm14 shell]# var2=$(date)
[root@vm14 shell]# echo $var2
2020年 03月 29日 星期日 22:26:28 CST
應用示例
# 根據日期生成日誌文件
[root@vm14 shell]# touch $(date +%Y%m%d).log
# 查看生成文件
[root@vm14 shell]# ls
20200329.log test1.sh test2.sh
命令替換會創建一個子shell來運行對應的命令。子shell( subshell)是由運行該腳本的shell
所創建出來的一個獨立的子shell( child shell)。正因如此,由該子shell所執行命令是無法
使用腳本中所創建的變量的。
在命令行提示符下使用路徑./運行命令的話,也會創建出子shell;要是運行命令的時候
不加入路徑,就不會創建子shell。如果你使用的是內建的shell命令,並不會涉及子shell。
在命令行提示符下運行腳本時一定要留心!
5. 輸入輸出重定向
5.1 輸出重定向
# > 覆蓋重定向, command > outputfile
# 將date命令的結果輸出到date.log文件中(會覆蓋之前內容)
[root@vm14 shell]# date > date.log
[root@vm14 shell]# cat date.log
2020年 03月 29日 星期日 22:35:03 CST
# >> 追加重定向, command >> outputfile
# 將date命令的結果輸出到date.log文件中(不覆蓋之前內容)
[root@vm14 shell]# date >> date.log
[root@vm14 shell]# cat date.log
2020年 03月 29日 星期日 22:35:03 CST
2020年 03月 29日 星期日 22:36:40 CST
5.2 輸入重定向
# < 文件輸入重定向, command < inputfile
# 計算文件test1.sh的行數、詞數、字節數
[root@vm14 shell]# wc < test1.sh
4 5 121
# 內聯輸入重定向( inline input redirection),格式如下
command << marker
data
marker
# 示例:
wc << EOF
TEST 1
TEST 2
TEST3
EOF
# 上例中EOF爲使用的marker,可以自己定義,比如定義成 END
wc << END
TEST 1
TEST 2
TEST3
END
# 上面兩個效果是一致的
6. 管道
管道:將上個命令的輸出,傳遞給下個命令當做輸入。
格式:command1 | command2 ,將command1的輸出,傳遞給command2當做輸入
# 將date命令的輸出,傳遞給wc命令作爲輸入
[root@vm14 ~]# date | wc
1 6 43
# ps -ef顯示全部進程,通過管道傳遞給grep命令,進行篩選
[root@vm14 ~]# ps -ef |grep ssh
root 6669 1 0 15:23 ? 00:00:00 /usr/sbin/sshd -D
root 62710 6669 0 21:42 ? 00:00:00 sshd: root@pts/0
root 62742 62715 0 21:44 pts/0 00:00:00 grep --color=auto ssh
7. 數學運算
7.1 expr命令
操作符與操作數之間必須要有空格
,且僅支持整數運算
。
# 加法
[root@vm14 ~]# expr 1 + 1
2
# 減法
[root@vm14 ~]# expr 4 - 1
3
# 乘法,需要對*進行轉義
[root@vm14 ~]# expr 1 \* 4
4
# 除法
[root@vm14 ~]# expr 4 / 3
1
expr命令支持的所有命令符列表
7.2 方括號
格式:$[num1 操作符 num2],數字與操作符之間空隔可有可無
,僅支持整數運算
。
# 加法
[root@vm14 ~]# echo $[1+2]
3
# 減法
[root@vm14 ~]# echo $[4 -1]
3
# 乘法,不需要對*進行轉義
[root@vm14 ~]# echo $[1*4]
4
# 除法
[root@vm14 ~]# echo $[4/3]
1
7.3 bash計算器
bash計算器能夠識別
- 數字(整數和浮點數)
- 變量(簡單變量和數組)
- 註釋(以#或C語言中的/* */開始的行)
- 表達式
- 編程語句(例如if-then語句)
- 函數
7.3.1 bash計算器初試:
# 安裝bash計算器
yum install bc
# 使用,命令行中輸入bc,然後回車
[root@vm14 ~]# 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'.
# 加法:輸入1.1+2.11,然後回車
1.1+2.11
3.21
# 減法:輸入4.21-1.1,然後回車
4.21-1.1
3.11
# 乘法:輸入1.99*1.21,然後回車
1.99*1.21
2.40
# 除法:輸入4/3,然後回車
4/3
1
# 精度問題,上面的除法只保留了整數部分,可以通過scale=4來設置保留4位小數
scale=4
# 重算除法
4/3
1.3333
# 重算乘法
1.99*1.21
2.4079
# 使用quit命令退出
quit
7.3.2 腳本中使用bc
# 示例1,使用$()
[root@vm14 ~]# var1=$(echo 'scale=4; 1.99*1.1'|bc)
[root@vm14 ~]# echo $var1
2.189
# 示例2,使用``
[root@vm14 ~]# echo `echo "scale=4; $var1*$var2"|bc`
2.189
# 示例3 使用內聯輸入重定向
echo $(bc << EOF
1.99*1.1
EOF
)
# 返回值
2.18
8. 退出腳本
8.1 退出狀態碼
shell中運行的每個命令都使用退出狀態碼( exit status)告訴shell它已經運行完畢。退出狀態碼是一個0~ 255的整數值,在命令結束運行時由命令傳給shell。可以捕獲這個值並在腳本中使用。
Linux提供了一個專門的變量$?
來保存上個已執行命令的退出狀態碼。
[root@vm14 ~]# date
2020年 03月 30日 星期一 22:31:09 CST
# 查看date命令的狀態碼,按照慣例,一個成功結束的命令的退出狀態碼是0。
[root@vm14 ~]# echo $?
0
# 如果一個命令結束時有錯誤,退出狀態碼就是一個正數值。
[root@vm14 ~]# date %m
date: 無效的日期"%m"
[root@vm14 ~]# echo $?
1
Linux退出狀態碼列表
8.2 exit命令
默認情況下, shell腳本會以腳本中的最後一個命令
的退出狀態碼退出。exit
命令允許你在腳本結束時指定一個退出狀態碼。
自定義狀態碼示例:
創建腳本/root/shell/test3.sh
,內容如下:
#!/bin/bash
# 自定義退出狀態碼
var1=10
var2=30
var3=$[$var1*$var2]
echo var3 is $var3
# 此處返回300
exit $var3
執行腳本
[root@vm14 shell]# sh test3.sh
var3 is 300
# 返回值是44,因爲狀態碼範圍是0-255,當返回值val超過這個範圍時返回:val % 256 > 0 ? val % 256 : val % 256 +256
# 此處val = 300 , 也就是返回300 % 256 =44
[root@vm14 shell]# echo $?
44
附錄:
expr命令符列表:
操作符 | 功能 |
---|---|
ARG1 | ARG2 | 如果ARG1既不是null也不是零值,返回ARG1;否則返回ARG2 |
ARG1 & ARG2 | 如果沒有參數是null或零值,返回ARG1;否則返回0 |
ARG1 < ARG2 | 如果ARG1小於ARG2,返回1;否則返回0 |
ARG1 <= ARG2 | 如果ARG1小於或等於ARG2,返回1;否則返回0 |
ARG1 = ARG2 | 如果ARG1等於ARG2,返回1;否則返回0 |
ARG1 != ARG2 | 如果ARG1不等於ARG2,返回1;否則返回0 |
ARG1 >= ARG2 | 如果ARG1大於或等於ARG2,返回1;否則返回0 |
ARG1 > ARG2 | 如果ARG1大於ARG2,返回1;否則返回0 |
ARG1 + ARG2 | 返回ARG1和ARG2的算術運算和 |
ARG1 - ARG2 | 返回ARG1和ARG2的算術運算差 |
ARG1 * ARG2 | 返回ARG1和ARG2的算術乘積 |
ARG1 / ARG2 | 返回ARG1被ARG2除的算術商 |
ARG1 % ARG2 | 返回ARG1被ARG2除的算術餘數 |
STRING : REGEXP | 如果REGEXP匹配到了STRING中的某個模式,返回該模式匹配 |
match STRING REGEXP | 如果REGEXP匹配到了STRING中的某個模式,返回該模式匹配 |
substr STRING POS LENGTH | 返回起始位置爲POS(從1開始計數)、長度爲LENGTH個字符的子字符串 |
index STRING CHARS | 返回在STRING中找到CHARS字符串的位置;否則,返回0 |
length STRING | 返回字符串STRING的數值長度 |
+ TOKEN | 將TOKEN解釋成字符串,即使是個關鍵字 |
(EXPRESSION) | 返回EXPRESSION的值 |
Linux退出狀態碼:
狀 態 碼 | 描 述 |
---|---|
0 | 命令成功結束 |
1 | 一般性未知錯誤 |
2 | 不適合的shell命令 |
126 | 命令不可執行 |
127 | 沒找到命令 |
128 | 無效的退出參數 |
128+x | 與Linux信號x相關的嚴重錯誤 |
130 | 通過Ctrl+C終止的命令 |
255 | 正常範圍之外的退出狀態碼 |