使用 shell 進行數學運算:
#!/bin/bash no1=4; no2=5; let result=no1+no2 echo $result result=$[ $no1 + no2 ] result=$(( no1 + 50 )) result=`expr 3 + 4` result=$(expr $no1 + 5) echo "4 * 0.56" | bc result=`echo "$no * 1.5" | bc` echo $result echo "scale=2;3/8" | bc #0.37 no=100 echo "obase=2;$no" | bc no=1100100 echo "obase=10;ibase=2;$no" | bc
將錯誤信息重定向到文件:
cmd 2>stderr.txt 1>stdout.txt #stderr 單獨重定向到一個文件,將 stdout 重定向到另一個文件 cmd &> output.txt #還可以利用更好的方法將 stderr 轉換成 stdout ,使得 stderr 和 stdout都被重定向到同一個文件中
tee 既可以將數據重定向到文件,還可以提供一份重定向數據的副本作為后續命令的 stdin 。在下面的代碼中, tee 命令接收到來自 stdin 的數據。它將 stdout 的一份副本寫入文件out.txt,同時將另一份副本作為后續命令的 stdin 。命令 cat -n 將從 stdin 中接收到的每一行數據前加上行號並寫入 stdout
$ cat a* | tee out.txt | cat -n cat: a1: Permission denied 1 a 2 a 3 a 4 a 5 a
$ cat out.txt
a1
a1
注意, cat: a1: Permission denied 並沒有在文件內容中出現。這是因為這些信息屬於 stderr ,而 tee 只能從 stdin 中讀取.默認情況下, tee 命令會將文件覆蓋,但它提供了一個 -a 選項,用於追加內容.如: $ cat a* | tee -a out.txt | cat –n 。
我們可以使用stdin所謂命令參數。只需要將-作為命令的文件名參數即可:$ cmd1 | cmd2 | cmd -
$ echo who is this | tee - who is this who is this
重定向時
> 等同於 1> ;對於 >> 來說,情況也類似(即 >> 等同於 1>> )。處理錯誤時,來自 stderr 的輸出被丟棄到文件/dev/null中。/dev/null是一個特殊的設備文件,它接收到的任何數據都會被丟棄。null設備通常也被稱為黑洞,因為凡是到這兒的數據都將一去不返。
有時需要對文本塊(多行文本)進行重定向,就像對標准輸入做的那樣。考慮一個特殊情況:源文本就位於shell腳本中。一個實用的例子是向log文件中寫入頭部數據。
a.sh
#!/bin/bash cat<<EOF>log.txt LOG FILE HEADER This is a test log file Function: System statistics EOF
在 cat <<EOF>log.txt 與下一個 EOF 行之間的所有文本行都會被當做 stdin 數據.
數組
#!/bin/bash arr=('f' 'z' 'k' 'b' 'a') #很多種方式創建數組 array_var[0]="test1" array_var[1]="test2" echo ${arr[2]} echo ${array_var[0]} echo ${#arr[*]} #獲取數組的長度 declare -A fruits_value #定義關聯數組 fruits_value=([apple]='100dollars' [orange]='150 dollars') echo ${fruits_value[apple]} echo ${!fruits_value[*]} #獲取數組的每個索引值,也可以用下面的方法 orange apple echo ${!fruits_value[@]}
別名:
alias install='sudo apt-get install' 就可以用install代替命令。但這樣關閉終端就會消失,可以在~/.bashrc中:echo 'alias cmd="command seq"' >> ~/.bashrc。如果需要刪除別名,只用將其對應的語句(如果有的話)從 ~/.bashrc 中刪除,或者使用 unalias 命令。或者使用 alias example= ,這會取消名為 example的別名。有些時候在我們建了別名的時候在使用命令時不想使用別名而是想使用原來的命令,在命令前加上\,像:\command
日期: 日期內容
星期 %a(例如:Sat)
%A(例如:Saturday)
月 %b(例如:Nov)
%B(例如:November)
日 %d(例如:31)
固定格式日期(mm/dd/yy) %D(例如:10/18/10)
年 %y(例如:10)
%Y(例如:2010)
小時 %I或%H(例如:08)
分鍾 %M(例如:33)
秒 %S(例如:10)
納秒 %N(例如:695208515)
Unix紀元時(以秒為單位) %s(例如:1290049486)
$ date +%s 1481029113 $ date --date "Thu Nov 18 08:07:21 IST 2010" +%s 1290047841 $ date --date "Jan 20 2001" +%A Saturday $date "+%d %B %Y" 06 十二月 2016
函數:
函數聲明:
function fname(){ statements; } 或者: fname(){ statements; }
調用:
fname arg1 arg2 ; #傳遞參數
$1 是第一個參數。
$2 是第二個參數。
$n 是第n個參數。
"$@" 被擴展成 "$1" "$2" "$3" 等。
"$*" 被擴展成 "$1c$2c$3" ,其中 c 是IFS的第一個字符。
"$@" 要比 "$*" 用得多。由於 "$*" 將所有的參數當做單個字符串,因此它很少被使用
$? 用來代替上一個指令的返回值。
開啟一個子shell:用(),在()中寫子shell的代碼
read命令:
(1) 下面的語句從輸入中讀取n個字符並存入變量 variable_name :
read -n number_of_chars variable_name
例如:
$ read -n 2 var
$ echo $var
(2) 用無回顯的方式讀取密碼:
read -s var
(3) 顯示提示信息:
read -p "Enter input:" var
(4) 在特定時限內讀取輸入:
read -t timeout var
例如:
$ read -t 2 var #在2秒內將鍵入的字符串讀入變量var
(5) 用特定的定界符作為輸入行的結束:
read -d delim_char var
例如:
$ read -d ":" var
hello: #var 被設置為 hello
書中有個例子,運行命令直至成功
repeat() { while true; do $@ && return; done }
在大多數現代系統中, true 是作為/bin中的一個二進制文件來實現的。這就意味着每執行一次 while 循環,shell就不得不生成一個進程。如果不想這樣,可以使用shell內建的“ : ”命令,它總是會返回為0的退出碼:
repeat() { while :; do $@ && return; done }
這里記住ture和:的區別就可以了。
用上面那個腳本的可能環境是下載一個文件的時候:repeat wget -c http://www.example.com/software-0.1.tar.gz
for 循環:
for var in list; #echo {1..50} 能夠生成一個從1~50的數字列表 do commands; done
for 循環也可以采用C語言中 for 循環的格式。例如:
for((i=0;i<10;i++)){ commands; #使用變量$i }
while 循環
while condition do commands; done
util循環
x=0; until [ $x -eq 9 ]; do let x++; echo $x; done
比較:
if condition; then commands; else if condition; then commands; else commands; fi
這里有一個技巧:if 和 else 語句可以進行嵌套。 if 的條件判斷部分可能會變得很長,但可以用邏輯運算符將它變得簡潔一些:
[ condition ] && action; # 如果 condition 為真,則執行 action ;
[ condition ] || action; # 如果 condition 為假,則執行 action 。
&& 是邏輯與運算符, || 是邏輯或運算符。編寫Bash腳本時,這是一個很有用的技巧。
算術比較
條件通常被放置在封閉的中括號內。一定要注意在 [ 或 ] 與操作數之間有一個空格。如果忘記了這個空格,腳本就會報錯。例如:
[$var -eq 0 ] or [ $var -eq 0] #這個是錯誤的 因為第一個$var 前和第二個 0的后沒有空格
對變量或值進行算術條件判斷:
[ $var -eq 0 ] #當 $var 等於 0 時,返回真
[ $var -ne 0 ] #當 $var 為非 0 時,返回真
其他重要的操作符如下所示。
-gt :大於。
-lt :小於。
-ge :大於或等於。
-le :小於或等於。
可以按照下面的方法結合多個條件進行測試:
[ $var1 -ne 0 -a $var2 -gt 2 ] #使用邏輯與-a
[ $var1 -ne 0 -o var2 -gt 2 ] #邏輯或 -o
字符串比較:
使用字符串比較時,最好用雙中括號,因為有時候采用單個中括號會產生錯誤,所以最好避開它們。
[[ $str1 = $str2 ]] :當 str1 等於 str2 時,返回真。也就是說, str1 和 str2 包含的文本是一模一樣的。
[[ $str1 == $str2 ]] :這是檢查字符串是否相等的另一種寫法。也可以檢查兩個字符串是否不同。
[[ $str1 != $str2 ]] :如果 str1 和 str2 不相同,則返回真。我們還可以檢查字符串的字母序情況,具體如下所示。
[[ $str1 > $str2 ]] :如果 str1 的字母序比 str2 大,則返回真。
[[ $str1 < $str2 ]] :如果 str1 的字母序比 str2 小,則返回真。
[[ -z $str1 ]] :如果 str1 包含的是空字符串,則返回真。
[[ -n $str1 ]] :如果 str1 包含的是非空字符串,則返回真。
注意在 = 前后各有一個空格。如果忘記加空格,那就不是比較關系了,而變成了賦值語句。
文件系統相關測試
[ -f $file_var ] :如果給定的變量包含正常的文件路徑或文件名,則返回真。
[ -x $var ] :如果給定的變量包含的文件可執行,則返回真。
[ -d $var ] :如果給定的變量包含的是目錄,則返回真。
[ -e $var ] :如果給定的變量包含的文件存在,則返回真。
[ -c $var ] :如果給定的變量包含的是一個字符設備文件的路徑,則返回真。
[ -b $var ] :如果給定的變量包含的是一個塊設備文件的路徑,則返回真。
[ -w $var ] :如果給定的變量包含的文件可寫,則返回真。
[ -r $var ] :如果給定的變量包含的文件可讀,則返回真。
[ -L $var ] :如果給定的變量包含的是一個符號鏈接,則返回真。
