平常開發基本都在linux環境下,bash命令用的很多,可是寫腳本的地方很少。真的寫起來,發現須要注意的語法、使用習慣的小問題仍是很多。linux
查了些資料,也結合本身工做中遇到的一些問題,列舉幾個須要注意的地方shell
用等號給變量賦值,=先後都不能有空格。bash
export能夠將其設爲環境變量,當前SHELL及子進程有效;父進程的自定義變量沒法在子進程中使用。測試
var=32 now=`date +%y%m%d%H` cur_path=`dirname $0` PATH=$PATH:/home/user/bin
declare -x var也可講變量設爲環境變量。變量賦值,默認是string類型,經過declare命令可改爲其餘類型,好比:spa
declare -i sum=12+34 #i = integer declare -a ... #a = array
重定向:將命令的結果輸出到文件,而不是標準輸出(屏幕)。
code
> 寫入文件並覆蓋舊文件orm
>> 加到文件的尾部,保留舊文件內容。three
單引號 '進程
兩個單引號包圍起來的字符串就是普通的字符串,它將保留原始的字面意思。ip
雙引號"
兩個雙引號包圍起來的字符串,部分特殊字符將起到它們的做用.
這些特殊字符有: 美圓符$, 反斜槓\, 反引號', 感嘆號!.
反引號 `
兩個反引號包圍起來的字符串,將做爲命令來運行,
執行的輸出結果做爲該反引號的內容,稱爲命令替換,
它有另外一種更好的寫法: $(command)
tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`
if [ ... ] then
...
elif ... then
...
else
...
fi
用" [ ] "來表示條件測試。注意這裏的空格很重要!要確保方括號的空格。
[ -f "somefile" ] :判斷是不是一個文件
[ -x "/bin/ls" ] :判斷/bin/ls是否存在並有可執行權限
[ -n "$var" ] :判斷$var變量是否有值
[ "$a" == "$b" ] :判斷$a和$b是否相等
-eq 等於
-ne 不等於
-gt 大於
-ge 大於等於
-lt 小於
-le 小於等於
? : 變量未定義,則顯示提示語word,腳本執行結束;
- : 變量未定義, 則使用新值word; 不改變變量原來的狀態;
+: 變量定義, 則使用新值word; 不改變變量原來的狀態; 與?不一樣的是,腳本不會中止執行;
=: 變量未定義, 則使用新值word, 並定義到變量;
變量有未定義與空值之分,要同時對這兩種狀況都進行判斷,能夠在上面的方法中加入冒號: 增長功能:
例如:
$ # a is undefined $ b="" $ c="Z" $ echo a=${a-1}, b=${b-2}, c=${c-3} a=1, b=, c=Z $ echo a=${a:-1}, b=${b:-2}, c=${c:-3} a=1, b=2, c=Z
位置變量:$1~$9, 表明傳入給執行腳本的參數,從1開始,最多能夠有9個。例如,下面的腳本根據輸入的名字實現重命名功能:
#!/bin/sh # rename: - rename a file # Usage: rename oldname newname oldname=$1 newname=$2 mv ${oldname:?"missing"} ${newname:?"missing"}
若是傳入的參數超過9個,或者說想傳入任意數量的參數,能夠用shift命令,來移除傳入的參數,例如:
#!/bin/sh arg1=$1;shift; arg2=$1;shift; arg3=$1;shift; echo first three arguments are $arg1 $arg2 and $arg3
#!/bin/sh arg1=$1 arg2=$2 arg3=$3;shift 3 echo first three arguments are $arg1 $arg2 and $arg3
$0 - 腳本名字
$* - 全部的位置參數
使用這個變量,一樣能夠操做超過10個的位置參數。例以下面這個腳本,能夠把任意多個的文件移動到一個文件夾下:
#!/bin/sh # scriptname: moveto # usage: # moveto directory files..... directory=${1:?"Missing"};shift mv $* $directory 調用的方法: ./moveto.sh /mytmp *.txt
$@ - 全部的位置參數(參數可包含空格)
此變量與$*的基本功能相似,不一樣的地方是,@能夠處理包含空格的參數。空格能夠分隔輸入參數,若是輸入參數包含空格,$@能夠返回包含空格的參數,$*則不能。能夠參考下面的例子來理解:
首先有一個打印變量名的腳本EchoArgs
#!/bin/sh # ================ # usage: # echoes arguments # ================ E="echo -n" # echo the name of script ${E} $0: # now echo each argument ${E} "'${1-"?"}'" ${E} "'${2-"?"}'" ${E} "'${3-"?"}'" ${E} "'${4-"?"}'" ${E} "'${5-"?"}'" ${E} "'${6-"?"}'" ${E} "'${7-"?"}'" echo
再寫一個測試腳本TestEchoArgs.sh
#!/bin/sh # ================ # usage: # test echoes arguments # ================ ./EchoArgs $* ./EchoArgs $@ ./EchoArgs "$*" ./EchoArgs "$@"
測試輸入結果,比較兩個命令的不一樣:
./TestEchoArgs.sh "a b c" 'd e' f g 輸出: ./EchoArgs:'a''b''c''d''e''f''g' ./EchoArgs:'a''b''c''d''e''f''g' ./EchoArgs:'a b c d e f g''?''?''?''?''?''?' ./EchoArgs:'a b c''d e''f''g''?''?''?'
分析:
./EchoArgs $* ./EchoArgs $@ 前兩個沒放在""中,結果同樣,由於$*和$@的執行以後都是傳給EchoArgs由空格分隔的七個參數 ./EchoArgs "$*" 因爲$*不能分辨有空格的參數,最後傳給EchoArgs的只有一個""的參數 ./EchoArgs "$@" $@在""中分辨出有四個參數,前兩個參數中有空格。
$# - 參數個數
shift $#能夠去掉全部的傳入參數。
$$ - 當前進程的ID
因爲進程的ID都是不一樣的,這個變量能夠用來命名惟一的臨時文件。例以下面這個腳本,返回行數:
#!/bin/sh # ************************************** # usage: # count lines of input file/files # ************************************** tempfile=/tmp/$0.$$ for i in $@ do if [ -f $i ]; then cat $i >> $tempfile fi done echo `wc -l $tempfile` lines were found /bin/rm $tempfile
另外一個用處是,能夠在其餘進程中經過$$來kill這個進程。例如:
echo $$ >/tmp/job.pid kill -HUP `cat /tmp/job.pid`
$! - 後臺進程的PID
只有運行&命令的進程纔會改變$!.使用此命令能夠控制多個後臺運行的程序,好比:
#!/bin/sh job1 & pid=$! job2 & pid="$pid $!" job3 & pid="$pid $!" trap "kill -15 $pid" 0 1 2 15 wait
$? - 錯誤狀態
返回前一個程序的退出狀態。
----------
未完,不定時更新...
Last updated - 2/23/2016