[bash]bash 筆記
Shell
#!/bin/bash
#
:<<BLOCK
BLOCK
#!/usr/bin/ruby
:<<BLOCK
REGEX
\ 跳脫字元
^
$
*等價於{0,} 匹配前面的紫表達式任意次 zo* z zo zoo
+ 匹配>=1次 zo+ zo zoo 等價 {1,}
? 匹配0次或1次 do(es)? do does 等價{0,1}
{n} 匹配n次 o{2} food
{n,} 至少匹配n次
{n,m} 匹配最少n次最多m次
? 非貪婪
. 匹配除"\r\n" 之外的所有字符, 若要匹配包含"\r\n" 在內的所有字符,請用 "[\s\S]"
()
x|y z|food z,food,zood; (z|f)ood zood,food
BLOCK
Shell 特殊符號
" => 用來使 shell 無法辨識出字符 $ ` \ 以外的任何字符或字串,又稱為弱引用
’ => 用來使 shell 無法辨識出所有特殊字符,也稱之為強引用
` => 將當前命令優先執行
; => 允許在一行上放多個命令
& => 背景執行,通常會加上 nohup
{} => 建立命令區塊
<>& => 重新定向
*? []! 模式匹配
$ 變數開頭
# 表示注釋(第一行除外)
; => 允許在一行上放多個命令
& => 背景執行,通常會加上 nohup
{} => 建立命令區塊
<>& => 重新定向
*? []! 模式匹配
$ 變數開頭
# 表示注釋(第一行除外)
變數與運算符號
變數名稱="變數"
readonly 變數名稱=“變數” 不能被改變
echo $變數名稱
set 顯示本地所有變數
unset 變數名稱清除變數值
readonly 顯示當前 shell 下唯讀變數
readonly 變數名稱=“變數” 不能被改變
echo $變數名稱
set 顯示本地所有變數
unset 變數名稱清除變數值
readonly 顯示當前 shell 下唯讀變數
變數設定在
$HOME/.bash_porfile(/etc/porfile)
$HOME/.bash_porfile(/etc/porfile)
設定環境變數
export test=“123”
查看
env、export
env、export
#!/bin/bash
# shell 支援的位置變數有10個,超過要用其他方法表示
echo "第一個變數: $0"
echo "第十個變數: $9"
echo "第十一個變數: ${10}"
特殊變數$* $@ 表示所有的位置參數
$#表示位置參數的總數
$#表示位置參數的總數
bash -x 可以拿來測試 shell 會印出每一行,在印出每一行的執行結果
如果只想測試某幾段的話可以使用
set -x
測試段落
set +x
測試段落
set +x
來測試
一個UNIX PROCESS或命令終止時,將會向父進程返回一個 exit 狀態,
若該進程成功執行完畢,則會返回一個數值為0的出口狀態,異常則非0。
若該進程成功執行完畢,則會返回一個數值為0的出口狀態,異常則非0。
在 Shell 中,可以用 exit[n] 來指定返回的exit 狀態,其中 n=0~255
eric@ubuntu:~/script$ cat test.sh
#!/bin/bash
echo "first paramater: ${10}"
echo $PWD #當前目錄
echo $RANDOM #每次引用會隨機產生0~32767的值
echo $SCONDS #腳本已運行秒數
echo $PPID #當前進程的父進程ID
echo $? #最近一次執行的命令或 shell 腳本的exit狀態
echo $EDITOR
echo $HOME
echo $PATH
eric@ubuntu:~/script$ ./test.sh
first paramater:
/home/eric/script
24326
13585
0
/home/eric
/home/eric/.nvm/versions/node/v8.11.3/bin:/home/eric/bin:/home/eric/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
shell 中並未嚴謹區分變數的類型,但可以使用 typeset、declare 定義變數的類型,並在定義的同時進行初始化。
declare -A dict
dict=([key1]="value1" [key2]="value2" [key3]="value3")
for d in ${dict[@]}
do
echo $d
done
eric@ubuntu:~/script$ ./test.sh
value3
value2
value1
常用命令
:<<BLOCK
冒號(:) 與 true 語句不執行任何實際的處理動作,但可以用於返回一個 exit 0 的測試條件
while :
搭配 sleep 可實現秒級別的 cron 任務
while :
do
...
sleep 1
done
---
echo、print 常與 awk 搭配
BLOCK
#!/bin/bash
echo -n "Enter your name: "
read name
echo "hello $name, welcome!"
# 使用 -p 可以直接在 read 中提示輸入,省去一行
read -p "Enter your name: " name
echo "hello $name, welcome!"
exit 0
set、unset
# set 用於修改或重新設定位置參數的值,不太任何參數時輸出所有內部變數
set -- #用於清除所有位置參數
a=34
unset a # 用於清除變數,將變數設為 null
expr
exp1+exp2
exp1-exp2
exp1/*exp2
exp1/exp2
exp1%exp2
#compare string
str1=str2
#will return boolean
命令替換
#!/bin/bash
today=$(date)
echo $today
unset today
today=`date`
echo $today
test 語句
test + if/then + case 組成shell的控制轉移結構
test expression # if ture return exit 0 else return exit num
[ expression ] #需要空格
[[expression]]
文件測試運算符
用於測試文件的狀態和屬性。
-e file # if exist
-r file # exist && readable
-w file # exist && writeable
-x file # exist && excuteable
-s file # exist && size >0
-f file # exist && is a normal file
-d file # exist && is a dir
-L file # exist && is a link file
-c file # exist && 字符特殊文件
-b file # exist && 塊特殊文件
-p file # exist && pipe 文件
常用舉例:
BACKDIR=/data/backup
[ -d ${BACKDIR} ] || mkdir -p ${BACKDIR}
[ -d ${BACKDIR}/${DATE} ] || mkdir ${BACKDIR}/${DATE}
[ ! -d ${BACKDIR}/${OLDDATE} ] || rm -rf ${BACKDIR}/${OLDDATE}
字符測試運算符
-z str # if the length of string is 0 return true
-n "str" # if the length of string is not 0 return true
s1=s2 #
s1!=s2
s1<s2
if[[ "$a"<"$b" ]]
if[[ "$a"/<"$b" ]]
整數測試運算符
# test 中的整數值比較會採用 c 的 atoi() 將字符轉換成等價的ASC,所以可以用數字字串跟整數比較
-eq # =
-ne # !=
-gt # >
-lt # <
-ge # >=
-le # <=
邏輯運算符
(expression) # 用於計算括號中的組合表達式,若結果為真回傳真
!exp # 可針對表達式進行邏輯非運算,即對測試結果求反,例如: test! -f file1
-a 、 &&
-o 、 ||
cmd1 && cmd2
cmd1 && cmd2
自訂 function
#!/bin/bash
:<<BLOCK
function name()
{
action;
[return 數值;]
}
# return 值 0~255 如果不加,將以最後一條命令的執行結果當作返回值
BLOCK
function traverse(){
for file in `ls $1`
do
if [ -d $1"/"$file ]
then
traverse $1"/"$file
else
echo $1"/"$file
fi
done
}
traverse "${PWD}"
字串擷取
#!/bin/bash
#shell 中的字串擷取
#第一種
varible=hello
echo "varible = ${varible}"
string=h
# #、% : 控制方向,#由左至右,%由右至左,一個代表取締一個,兩個代表曲最後一個
echo ${varible##*${string}} #ello 由左向右擷取最後一個string 後的字串
string=l
echo ${varible#*${string}} #lo 從左向右擷取第一個string後的字串
echo ${varible%%${string}*} #he 由右至左曲最後一個string後的字串
echo ${varible%${string}*} #hel 由右向左曲第一個string後的字串
#第二種,直接設定開始結束位置
echo '--- method 2 ---'
echo ${varible:0:2} # he
echo `ls -al |cut -d "." -f2`
Array
#!/bin/bash
:<<BLOCK
#define
array_name=(value0 value1 value2 value3)
array_name=(
value0
value1
value2
value3
)
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
#read
#${array_name[index]}
value=${array_name[2]}
BLOCK
name=(
aaa
bbb
ccc
ddd
)
# read by index
echo "first index: ${name[0]}"
echo "second index: ${name[1]}"
# read all
echo "${name[*]}"
echo "${name[@]}"
# get array length
length=${#array_name[@]}
length=${#array_name[*]}
字典檔(key-value pair)
#!/bin/bash
# 一定要先宣告,在進行定義
declare -A dic
dic=([key1]="value1" [key2]="value2" [key3]="value3")
#print value of key
echo ${dic[key3]}
#print all keys
echo ${!dic[*]}
#print all values
echo ${dic[*]}
#print all key value
for key in $(echo ${!dic[*]})
do
echo "$key : ${dic[$key]}"
done
shell 中的控制結構
if
then
...
else
...
fi
---
if [[ a -eq b ]]
then
...
elseif [[ a -le b ]]
then
...
else
...
fi
#!/bin/bash
if [ "10" -lt "12" ]
then
echo "10 < 12"
else
echo "10 > 12"
fi
case
case value in
1)
command1
;;
2)
command2
;;
*)
command3
esac
留言
張貼留言