shell基礎:
sh命令:
參數:
-c string 將string當作命令來執行。注意區別:string是用單引號擴起來的還上用雙引號擴起來的!
-x xxx.sh 開啓調試模式,shell在執行腳本的過程中把它實際執行的命令都顯示出來,並且在命令的行首顯示一個"+"號(shell內置變量PS4='+ '),同set -x。
補充:可以通過修改$PS4的值,從而使每一條實際執行的命令前面顯示其行號以及所屬的函數名。eg:先執行export PS4='+{$LINENO:${FUNCNAME[0]}} ', 然後再使用“-x”選項來執行腳本。
-n 不執行腳本,而是去讀一遍腳本中的命令,目的是爲了檢查腳本中的語法錯誤。
# !/usr/bin/env bash
說明:腳本解釋器在linux中可能被安裝在不同的目錄,而env可以在系統的PATH目錄中查找,故腳本用env啓動。
命令 -/+參數
-參數 設置某個參數
+參數 取消某個參數的設置。
set命令:
參數:
無參 列出所有的環境變量。
-e 當命令的返回值不等於0(即執行該命令報錯)時,立即退出shell。
+e 表示取消-e參數,即當命令的返回值不等於0時,不會立即退出shell,而是會繼續執行shell腳本。
-x 開啓調試模式。
declare命令:
說明:用於聲明shell變量
參數:
-r 將變量聲明爲只讀變量。eg:declare -r name=jack
-x 將變量設置爲環境變量,該變量可供shell以外的程序來使用。
echo命令:
參數:
-e 將特殊字符進行轉義。
\a 發出警告聲
\c 最後不加換行符號
\f 換行但光標仍舊停留在原來的位置
\n 換行且光標移至行首
\r 光標移至行首,但不換行
\t 插入tab
let命令:
說明:let命令是bash中用於計算的工具,用於執行一個或多個表達式,變量計算中不需要加上$來表示變量。如果表達式中包含了空格或其他特殊字符,則必須引起來。
舉例:
let i=i+1
let i++
mail命令:
方式一:
在shell窗口中編輯內容,編輯完成後按ctrl+d退出編輯環境,郵件即可發送。
mail -s "郵件主題" [email protected]
方式二:
mail -s "郵件主題" [email protected] < content.txt
方式三:
echo "mail content" | mail -s "郵件主題" [email protected]
補充:
ctrl+c 終止當前任務命令或程序。
ctrl+d 退出當前用戶環境,相當於exit。
exit命令:
如果在管道中使用exit,則只會退出當前管道,並不會退出整個腳本進程。
命令行參數
$0 腳本的名字
$1, $2, ..., $9 腳本第1個到第9個命令行參數
$# 命令行參數的個數
$* 以“參數1 參數2 參數3..” 的形式返回所有命令行參數的值
$@ 以“參數1”“參數2”“參數3”.. 的形式返回所有命令行參數的值
$? 最後一條命令的退出狀態碼(執行成功返回0,執行失敗返回1)
$$ 正在執行的進程的ID(PID)
getopts命令:
概念:獲取命令行的參數。
格式:getopts argString varName
說明:
1)參數後面加冒號表示該參數可以接受賦值。
2)若argString以冒號開頭,則表示忽略錯誤。eg:
若argString爲 a: 那麼,a必須賦值,否則會報錯。
若argString爲 :a: 那麼,a即使不賦值,也不會報錯。
使用:
while getopts :i:na: opt
do
case ${opt} in
i) echo 'this is param i value '$OPTARG
;;
n) echo 'has param n'
;;
a) echo 'this is param a value '$OPTARG
;;
esac
done
# 驗證:sh my.sh -i 99 -n -a asdf
變量:
引用變量:
${variable}
$variable
清除變量:
unset variable
變量替換
$variable 保存在variable中的值
${variable} 保存在variable中的值
${variable:-string} 如果variable的值非空,則值爲variable,否則值爲string
${variable:+string} 如果variable的值非空,則值爲string,否則值爲空
${variable:=string} 如果variable的值非空,則值爲variable,否則值爲string且variable的值設置爲string
${variable:?string} 如果variable的值非空,則值爲variable,否則顯示string並退出
引號的說明【重要】:
單引號括起來的的字符都作爲普通字符對待。
雙引號括起來的字符,除$、\、'(單引號)、"(雙引號)之外,其餘字符作爲普通字符對待。
反引號括起來的字串被shell解釋成命令,在執行時,shell首先執行該命令,並以它的標準輸出結果取代整個反引號部分。
將命令的執行結果賦值給變量:
# 將某個shell命令的執行結果賦給某個變量。注:賦值號“=”的左右兩邊不能直接跟空格,否則shell會將其視爲命令。
variableName=`command`
variableName=$(command)
定義系統提示符的變量
eg:PS1='[\u@\t \w]\$ '
\u:顯示當前用戶名
\h:顯示簡寫主機名。如默認主機名“localhost”
\$:提示符。如果是root用戶會顯示提示符爲“#”,如果是普通用戶會顯示提示符爲“$”
\w:顯示當前所在目錄的完整名稱
\W:顯示當前所在目錄的最後一個目錄
\t:顯示24小時制時間,格式爲“HH:MM:SS”
\T:顯示12小時制時間,格式爲“HH:MM:SS”
\d:顯示日期,格式爲“星期 月 日”
\A:顯示24小時制時間,格式爲“HH:MM”
\#:執行的第幾個命令
字符串函數:
${#str} 獲取字符串的長度
${str:num1:num2} 表示從字符串的第num1個字符開始,截取num2個字符。
${str/str1/str2} 將第一個str1替換爲str2
${str//str1/str2} 將所有的str1替換爲str2
${str#*pattern} 刪掉第一個pattern及其左邊的字符串
${str##*pattern} 刪掉最後一個pattern及其左邊的字符串
${str%pattern*} 刪掉最後一個pattern及其右邊的字符串
${str%%pattern*} 刪掉第一個pattern及其右邊的字符串
說明:#是去掉左邊,%是去掉右邊(tip:鍵盤上#在%的左邊)、單一符號是最小匹配,兩個符號是最大匹配。
數組:
定義:shell中的數組用括號來表示,元素之間用空格分隔。
初始化:
方式一:myArray=(element1 element2 element3)
舉例:將一個只有一列數據的文件中的數據初始化到數組中:myArray=(`cat /data/mydata.txt`)
方式二:
myArray[0]=element1;
myArray[1]=element2;
myArray[2]=element3;
獲取數組的元素:
${myArray[index]} 獲取下標爲index的數組
${myArray} 或 ${myArray[0]} 獲取數組的第一個元素
${myArray[*]} 或 ${myArray[@]} 獲取數組的所有元素
${#myArray[*]} 獲取數組的長度
條件判斷:
概念:表達式用中括號[]或雙中括號[[]]括住,條件表達式與左右方括號之間必須都保留一個空格。
說明:單中括號中的變量必須要加雙引號,雙中括號中的變量不用加雙引號。
舉例:[ -z "$pid" ] VS [[ -z $pid ]]
參數:
邏輯運算符:
&& expr1 && expr2 邏輯與(短路與)
|| expr1 || expr2 邏輯或(短路或)
! 邏輯非
數值判斷:
-eq num1 -eq num2 是否相等
-ne num1 -ne num2 是否不相等
-gt num1 -gt num2 是否大於
-ge num1 -ge num2 是否大於等於
-lt num1 -lt num2 是否小於
-le num1 -le num2 是否小於等於
字符串判斷:
= str1 = str2 字符串是否相等,注意:"="兩邊必須有空格!
!= str1 != str2 字符串是否不等
-n -n str1 字符串是否非空
-z -z str2 字符串是否是空串(長度是否等於0 z:zero)
文件判斷:
-e -e filenaem 文件是否存在
-r -r filename 文件是否存在且可讀
-w -w filename 文件是否存在且可寫
-s -s filename 文件是否存在且長度非0
-f -f filename 文件是否存在且是普通文件
-d -d filename 文件是否存在且是一個目錄
-L -L finename 文件是否存在且是一個鏈接
循環:
格式:
while [ condition ]
do
# do something
done
無限循環:
while :
do
# do something
done
讀文件:
# 方式一:read通過輸入重定向,把file的第一行所有的內容賦值給變量line,循環體內的命令一般包含對變量line的處理;然後循環處理file的第二行、第三行。。。一直到file的最後一行
while read line
do
# do something
done < file
# 方式二:command命令的輸出作爲read循環的輸入,這種結構常用於處理超過一行的輸出。
command | while read line
do
# do something
done
舉例1:
#!/usr/bin/env bash
# 從數據庫中導出的數據,每行數據以製表符分隔
path=/home/jxn/updateData.tsv
# 計數
count=0;
echo "--------- start"
# 按行讀取文件的內容
while read line
do
# 將每行的內容轉換爲數組
dataArray=(${line});
firstFieldValue=${dataArray[0]};
secondFieldValue=${dataArray[1]};
updatesql="update mytable set firstField=\"${firstFieldValue}\" where secondField=\"${secondFieldValue}\"";
# 執行sql
echo sql=${updatesql};
result=`/home/jxn/tools/mysql -h myhost -P 3306 -uroot -p'root!@#' dbName -e "${updatesql}"`;
# 計數
let count=count+1;
echo "---------result=[${result}] count=[${count}] "
done < ${path}
echo "--------- end"
舉例2:
#!/usr/bin/env bash
# 對文件中的每行數據進行處理後,通過管道輸出。
for line in $(cat mydata.txt);
do
printf $line | awk '{print $1}'; # 注意,這裏需要分號結尾。
done | sort | uniq -c > result.txt