shell script(BASH)的使用注意事項

Author:kawsing 2004/03/06

觀念
執行script時,預設使用子shell,若要在原shell執行,要使用
. script檔 或 source script檔
子shell會繼承父shell的環境變數,不會繼承父shell的變數

設定變數
變數=變數值

設定環境變數
變數=變數值;export 變數
export 變數=變數值
declare -x 變數=變數值

取用變數
一般
$變數
周圍有字
abc${變數}def

 

清空變數
1.變數=
2.unset 變數(函數)

設定陣列
直接指定
a[0]=1
a[1]=2
a[2]=3
函數指定
a=(1 2 3)
以字串為索引
a["bash"]="字串索引"

取用陣列元素
${a[0]}
${a["bash"]}

一組的命令
開子shell
(command1;command2;command3;...)
原shell執行
{ command1;command2;command3;... }
***{}的左右要有空白***

連續的命令
command1;command2;command3==>連續執行命令
command1 && command2 && command3==>一個命令成功才執行下一個
command1 || command2 || command3==>一個命令不成功才執行下一個

一些特殊字元
\b 後退
\f 跳頁
\n 換行字元
\r return
\t TAB

進階的變數設定
result=${str:-value}
 str=非空
result=str
str=
result=value

result=${str:=value}
str=
result=value同時str=value

result=${str:?msg}
str=非空
result=str
str=
顯示錯誤訊息msg

result=${str:+value}
str=非空
result=value
str=
不做取代

截取變數
r="/usr/local/bin/sftp"
path=${r##*/}
path=sftp

path=${r#*/}
path=usr/local/bin/sftp

path=${r%%/*}
path=

path=${r%/*}
path=/usr/local/bin

eval兩次掃描命令
n="兩次代換變數"

 

 


str=$n
eval echo \$$str
顯示-->兩次代換變數

一些觀念
cat < text==>將鍵盤輸入改由text檔案提供
cat text==>顯示text檔案內容
[ab]==>ab任一字元
[!ab]==>非a非b的其他任一字元,注意,在正規表示式中,以^表非,[^A-Z]表非大寫字母
`命令`=$(命令)==>執行命令(命令代換)
back slash(\)==>跳脫符號
$?==>用來存判斷後的傳回值,0是真,非0是假

正規表示式(Regular Expressions)
意義:一種描述,表示某種樣式某些樣式的組合
樣式寫法:
.==>任一字元
\==>跳脫字元
^==>表一列的開頭
$==>表一列的結尾
*==>任何字元
[]==>[abc]表a或b或c
\{ \}==>指定保留的個數
\( \)==>保留符合的部分
\1==>位置參數

sed指令
格式:sed '樣式' 檔案
意義:一種非交談式串流編輯語言
//在sed中表示搜尋
例子:
sed '1,4d' file
sed '/[0-9]\{3\}/d' file==>把含有3個數字的列刪除
sed '/^$/d' file
sed '/abc/p' file==>將有abc的列顯示出,但不符合的也會顯示
sed -n '/abc/p' file==>將有abc的列顯示出,但不符合的不會顯示(-n 不秀出全部)
sed -n 's/abc/def/p' file==>將有abc的列取代成def,並只會取代一列
sed -n 's/abc/def/gp' file==>將有abc的列全部取代成def(g是全部)
sed -n 's/abc//p' file==>將有abc的列的abc刪除
sed -n 's/^...//' file==>將每列的開頭三個字元去掉
sed -n 's/...$//' file==>將每列的結尾三個字元去掉
sed -n 's/\(abc\)/\1def/p' file==>把\(abc\)保留在\1中,並作取代
sed -n '/AAA/s/abc/def/p' file==>搜尋有AAA的列,將其中的abc取代成def
sed -n '/AAA/,/DDD/s/abc/def/p' file==>搜尋有AAA直到DDD的列,將其中的abc取代成def
sed -n '2,5s/abc/def/p' file==>取代2-5列

awk指令
格式:awk '樣式' file==>顯示符合樣式的列
         awk '{動作}' file==>對每一列執行{}中的動作
         awk '樣式{動作}' file==>符合樣式的列執行{}中的動作
意義:此指令用於處理資料並產生報告
例子:
awk '/abc/' file
awk '{ print $1,$2 }' file
awk '/abc/{ print $1,$2 }' file
awk -F: '/kawsing/{ print $1,$3,$5 }' /etc/passwd(-F 指定分隔符號)
awk -F: 'BEGIN{ OFS="+++" }/kawsing/{ print $1,$3,$5 }' /etc/passwd(BEGIN指定開始的動作,OFS設定分隔符號)

算數運算
m=4+5
echo $m的結果顯示4+5,視為字串
所以,在Bash shell中使用算數運算,要一下面四種方法進行:

  1. expr(外部指令)
    m=`expr 4 + 5`
    m=`expr 4 \* 5`
    m=`expr $m + 1`
    不能運算乘冪羽求餘數(%)
  2. $(())
    m=$(( 4 ** 5 ))==>4的5次方
    m=$(( $m + 1 ))
    m=$(( 5 % 4 ))
  3. $[]
    m=$[ 4 \* 5 ]
    m=$[ 4 ** 5 ]
    m=$[ m + 1 ]
  4. let(內建指令)
     let m=m+1(注意與上面的不同處,無空白$跳脫)
     let m=4+5
    let m=4**5

位置參數
Bash shell可以傳遞參數,使用位置參數
$0==>script檔案本身
$1~$9==>檔案的9個參數
$10==>$1加上0,$1是A,則$10就是A0
$#==>參數總數
$*==>所有參數,但"$*"="ABCDEFGHI"
$@==>所有參數,但"$@"="A" "B" "C" "D" "E" "F" "G" "H" "I"
shift==>向左移動參數
set==>重設參數,set a b c d將參數重設為$1=a,$2=b...

運算子(operator)
數字判斷
-eq
-ne
-ge
-le
-gt
-lt
(( "3" > "2"))==>可用><=比較數字
字串判斷
=與==   string1與string2相同
>  string1排序大於string2==>[ "string1" \> "string2" ]  \>去掉>的特殊意義
<
!=
-n  string長度不為0
-z  string長度為0,即空字串
邏輯判斷
-a==>且
-o==>或
!==>非
檔案判斷
-a 檔案存在
-b 檔案存在且是block檔
-c 檔案存在且是character檔
-d 檔案存在且是目錄
-e 檔案存在
-f  檔案存在且是正規檔
-g 檔案存在且是set-gid
-h 檔案存在且是符號連結檔
-k 檔案存在且sticky位元已設定
-p 檔案存在且是FIFO
-r 檔案存在且可讀
-s 檔案存在且大小大於0
-t fd 檔案代碼 fd 已開啟且連接到一個終端機
-u 檔案存在且uid位元已設定
-w 檔案存在且可寫
-x 檔案存在且可執行
-O 檔案存在且被有效的使用者id所擁有
-G 檔案存在且被有效的群組id所擁有
-L 檔案存在且是符號連結檔
-S 檔案存在且是socket
-N 檔案存在且自它上次被讀取之後已被修改過
-nt newer than
-ot older than
-ef 有相同的設備和 inode 編號

流程控制
選擇結構
if [ 條件式 ]; then
command...
elif [ 條件式 ];then
command...
else
command...
fi

case 變數  in
s1)command...
;;
s2)command...
;;
s3)command...
;;
*)command...
esac

重複結構--迴圈
for:
(1)
for 變數 in 範圍
do
command...
done
(2)
for (( i=0; i<5; i++ ))
do
command...
sleep sec==>可延遲sec秒後執行下一迴圈
done

while [ 條件式(真) ];then
do
command...
done

until [ 條件式(假) ]; then
do
command...
done

函式
function func(){
command...
}
function func{}
func(){}
執行函式
func


函式傳遞參數
function func(){
echo $1
}
func "hello"==>此hello就是$1
函式內部有使用其它變數,您不想讓此變數和外界相同的變數相互影響,可使用 local 這個關鍵字來宣告它
function localvar(){
local A
local B
}
A="haha"
B=35
變數同名但不相干

select選單
select 變數 in *; do
   if [ -z $變數值 ]; then
    break
   fi
echo "你選擇$變數值(you choose $REPLY)"
done

原文出處:http://b123.hlc.edu.tw/shellscript.htm

arrow
arrow
    全站熱搜

    風箏 發表在 痞客邦 留言(0) 人氣()