2008-05-16

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



原始來源:shell script(BASH)的使用注意事項

沒有留言: