#!/bin/bash MySQLSTARTUP="/data/3306/mysql" DbProcessCount=`ps -ef|grep mysql|grep -v grep|wc -l` DbPortCount=`netstat -lnt|grep 3306|wc -l` if [ $DbProcessCount -eq 2 ] && [ $DbPortCount -eq 1 ] then echo "mysql is running! " else $MySQLSTARTUP start >/tmp/mysql.log sleep 20; if [ $DbProcessCount -ne 2 ] || [ $DbPortCount -ne 1 ] then killall mysqld >/dev/null 2>&1 sleep 5 killall mysqld >/dev/null 2>&1 sleep 5 [ $DbPortCount -eq 0 ] && $MySQLSTARTUP start >>/tmp/mysql.log [ $? -eq 0 ] && echo "mysql is started" fi mail -s "mysql restarted" xx@qq.com < /tmp/mysql.log
fi
2) 經過鏈接mysql 執行命令來判斷mysql
#!/bin/bash MySQLSTARTUP="/data/3306/mysql" mysql -uroot -p'oldboy' -S /data/3306/mysql.sock -e "select version();" >/dev/null 2>&1 if [ $? -eq 0 ] then echo "mysql is running! " else $MySQLSTARTUP start >/tmp/mysql.log sleep 10; mysql -uroot -p'oldboy' -S /data/3306/mysql.sock -e "select version();" >/dev/null 2>&1 if [ $? -ne 0 ] then killall mysqld >/dev/null 2>&1 killall mysqld >/dev/null 2>&1 sleep 10 $MySQLSTARTUP start >>/tmp/mysql.log fi mail -s "mysql restarted" xx@qq.com < /tmp/mysql.log fi
3) 較專業的寫法:git
#!/bin/bash MYUSER=root MYPASS="" MYSOCK=/data/3306/mysql.sock MySQL_STARTUP="/data/3306/mysql" LOG_PATH=/tmp LOG_FILE=${LOG_PATH}/mysqllogs_`date +%F`.log MYSQL_PATH=/usr/local/mysql/bin MYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS -S $MYSOCK"
$MYSQL_CMD -e "select version();" >/dev/null 2>&1 if [ $? -eq 0 ] then echo "MySQL is running! " exit 0 else $MySQL_STARTUP start >$LOG_FILE sleep 5; $MYSQL_CMD -e "select version();" >/dev/null 2>&1 if [ $? -ne 0 ] then for num in `seq 5` do killall mysqld >/dev/null 2>&1 [ $? -ne 0 ] && break; sleep 1 done $MySQL_STARTUP start >>$LOG_FILE fi $MYSQL_CMD -e "select version();" >/dev/null 2>&1 && Status="restarted" || Status="unknown" mail -s "MySQL status is $Status" @qq.com < $LOG_FILE fi exit
例3 監控apacheweb
1) 對端口、進程和url同時監測。正則表達式
#!/bin/bash . /etc/init.d/functions LOG_FILE=/tmp/httpd.log apachectl="/application/apache/bin/apachectl"
HTTPPORTNUM=`netstat -lnt|grep 80|grep -v grep|wc -l` HTTPPRONUM=`ps -ef|grep http|grep -v grep|wc -l`
wget --quiet --spider http://10.0.0.179:8000 && RETVAL=$? [ ! -f $LOG_FILE ] && touch $LOG_FILE if [ "$RETVAL" != "0" -o "$HTTPPORTNUM" -lt "1" -o "$HTTPPRONUM" \< "1" ] ;then action "httpd is not running" /bin/false echo -e "httpd is not running\n" >$LOG_FILE echo "Preparing start apache..." for num in `seq 10` do killall httpd >/dev/null 2>&1 [ $? -ne 0 ] && { echo "httpd is killed" >$LOG_FILE break; } sleep 2 done $apachectl start >/dev/null 2>&1 && Status="started" || Status="unknown" [ "$Status" = "started" ] && action "httpd is started" /bin/true||\ action "httpd is started" /bin/false mail -s "`uname -n`'s httpd status is $Status" xx@qq.com <$LOG_FILE exit else action "httpd is running" /bin/true exit 0 fi
2) 使用nmap檢測sql
#!/bin/bash ip_add="$1" port="$2" print_usage(){ echo -e "$0 ip port" exit 1 } #judge para num if [ $# -ne 2 ] then print_usage fi PORT_COUNT=`nmap $ip_add -p $port|grep open|wc -l` #echo -e "\n" |telnet $ip_add $port||grep Connected #echo -e "\n"|telnet 10.0.0.179 8000|grep Connected [[ $PORT_COUNT -ge 1 ]] && echo "$ip_add $port is ok." || echo "$ip_add $port is unknown."
No.001 文件安全與權限 1. umask 決定了新建文件的權限 2. 軟連接(符號連接) ln -s source_path target_path No.002 find和xargs 1. find pathname -options [-print -exec -ok] 其中exec參數的命令格式: 'command-' {} \; 注意必須包含【{} \;】 -perm 按權限來查找 ex. find . -perm 755 -print -mtime 按修改時間來查找 ex. find / -mtime -5 -print 更改時間5天之內 find / -mtime +5 -print 更改時間5天之前 2. xargs與-exec和-ok相似,可是限制更少,也更快 3種參數的命令:find . -name "*.c" -exec wc -l {} \; find . -name "*.c" -ok wc -l {} \; 每次執行命令前有提示 find . -name "*.c" | xargs wc -l No.003 後臺執行命令 1. [crontab] [at] [&] [nohup]四種 No.004 文件名置換 1. 列出隱藏文件 ex. ls .* No.005 shell輸入與輸出 1. echo輸出時加上 -n 參數不換行, ex. echo -n "aaaa" 2. tee 命令能夠同時輸出到屏幕和文件中 ex. ls | tee file.out 3. 標準輸入 0 標準輸出 1 標準錯誤 2 4. 將標準輸出和標準錯誤輸入到一個文件 ex. command >file.out 2>&1 No.006 命令執行順序 1. 命令1 && 命令2 命令1執行成功後纔會執行命令2 2. 命令1 || 命令2 命令1執行失敗後纔會執行命令2 No.007 正則表達式 1. 正則表達式元字符及含義 ^ 只匹配行首 $ 只匹配行尾 * 匹配0次或屢次 [] 匹配[]內字符 \ 轉義符 . 匹配任意一個字符 pattern\{n\} 匹配pattern出現的次數,n次 pattern\{n, \} 同上,最少n次 pattern\{n, m\} 同上,次數在n與m之間 No.008 grep 1. grep 主要選項及其含義 -c 只輸出匹配行的行數 -i 不區分大小寫 -h 查詢多文件時不顯示文件名 -l 查詢多文件時只輸出包含匹配字符的文件名 -n 顯示匹配行及行號 -s 不顯示不存在或無匹配文本的錯誤信息 -v 顯示不包含匹配文本的全部行 2. 查詢空行 grep '^$' filename 3. 類名及等價的正則表達式 [[:upper:]] = [A-Z] [[:lower:]] = [a-z] [[:digit:]] = [0-9] [[:alnum:]] = [0-9a-zA-Z] [[:space:]] = 空格或tab鍵 [[:alpha:]] = [a-zA-Z] No.009 AWK # awk的主要做用在於將文本分紅各個區域,便於分別進行處理 1. awk -F指定分隔符,-f指定awk腳本 ex. awk -F: 'commands' input-file(s) ex. awk -f awk-script input-file(s) 2. awk 分隔出的域用$1,$2...$n來表示,其中$0表示全部域 3. awk 條件操做符 <, <=, >=, ==, != ~ 匹配正則表達式 !~ 不匹配正則表達式 4. awk 內置變量 ARGC 命令行參數個數 ARGV 命令行參數排列 ENVIRON 支持隊列中系統環境變量的使用 FILENAME awk瀏覽的文件名 FNR 瀏覽文件的記錄數 FS 設置輸入域分隔符,等價於命令行-F選項 NF 記錄的域個數 NR 已讀的記錄數 OFS 輸出域分隔符 ORS 輸出記錄分隔符 RS 控制記錄分隔符 ex. awk '{print NF,NR,$0} END{print FILENAME}' input-file 5. awk 字符串函數 gsub, index, length, match, split, sprint, sub, substr, substr 6. awk 中的printf函數能夠控制格式化輸出 7. awk 的循環結構 For (element in array) print array[element] No.010 sed # sed的主要做用在於過濾和查找文本中的特定內容 1. sed 命令格式: sed [options] sed-command input-file sed [options] -f sed-script input-file No.011 合併和分隔文件 1. sort, uniq, join, cut, paste, split No.012 tr的用法 1. 去除oops.txt中的重複字符 tr -s "[a-z]" < oops.txt 2. 去除oops.txt中的空行 tr -s "[\n]" < oops.txt 3. oops.txt中小寫轉大寫 tr -s "[a-z]" "[A-Z]" < oops.txt No.013 登陸環境 1. /etc/passwd 保存全部帳號的基本信息(不包括密碼) 2. /etc/profile 基本的配置信息,登陸時讀取此文件 3. $HOME/*profile 各個用戶的profile文件,會覆蓋系統的profile文件 4. $HOME/*logout logout(鍵入命令exit時)是執行的腳本 No.014 環境和shell變量 1. shell變量的設置方式 Variable-name=value 設置實際值到variable-name Variable-name+value 若是設置了variable-name,則重設其值 Variable-name:?value 若是未設置variable-name,顯示未定義用戶錯誤信息 Variable-name?value 若是未設置variable-name,顯示系統錯誤信息 Variable-name:=value 若是未設置variable-name,設置其值 Variable-name:-value 若是未設置variable-name,就用value,可是不設置variable-name 2. 設置只讀變量 readonly variable-name 3. export variable-name 能夠將變量導入到子shell中 4. shell腳本的參數 $0表示腳本名字,$1表示第一個參數......$9表示第九個參數 5. 特定shell變量 $# 參數個數 $* 用一個字符串顯示全部參數 $$ 腳本運行的當前進程ID $! 後臺運行的最後一個進程的進程ID $@ 與$*相同,每一個參數做爲獨立的字符串 $- 顯示shell的當前選項,與set命令相同 $? 顯示shell命令的退出狀態,0表示無錯誤,其餘表示有錯 No.015 引號 1. 雙引號("") 其中引用的變量會替換爲變量值。好比: [wangyb@localhost bash]$ STR="Hello world" [wangyb@localhost bash]$ echo "$STR" Hello world 2. 單引號('') 忽略變量和其餘特殊字符,單引號內任何內容都當成字符串顯示。好比: [wangyb@localhost bash]$ STR="Hello world" [wangyb@localhost bash]$ echo '$STR' $STR 3. 單引號和雙引號同時使用時,誰在外面誰起做用。好比 [wangyb@localhost bash]$ echo "'$STR'" 'Hello world' [wangyb@localhost bash]$ echo '"$STR"' "$STR" 4. 反引號(``) 反引號中的內容被當作命令來執行。好比 [wangyb@localhost bash]$ VAR=`date` [wangyb@localhos bash]$ echo $VAR Thu Dec 22 22:08:07 JST 2011 5. 轉義符(\) No.016 Shell腳本介紹 1. 腳本的第一行通常以 #!/bin/bash 開始 2. 給腳本加入執行權限後就能夠運行腳本了 #No.017 條件測試 1. 測試語法 test condition 或者 [ condition ] 使用方括號是注意在condition兩邊加上空格 2. 文件狀態測試 -d 目錄 -s 文件長度大於0 -f 正規文件 -w 可寫 -L 符號鏈接 -u 文件有suid位設置 -r 可讀 -x 可執行 例子以下:測試是否爲目錄,也能夠用 test -d bash.sh 來代替方括號 [root@localhost bash]# [ -d bash.sh ] [root@localhost bash]# echo $? 1 [root@localhost bash]# [ -d . ] [root@localhost bash]# echo $? 0 3. 邏輯與 -a 邏輯或 -o 邏輯否 ! 例子以下: [root@localhost bash]# [ -d bash.sh -a -d . ] [root@localhost bash]# echo $? 1 [root@localhost bash]# [ -d bash.sh -o -d . ] [root@localhost bash]# echo $? 0 [root@localhost bash]# [ ! -d bash.sh -a -d . ] [root@localhost bash]# echo $? 0 [root@localhost bash]# [ ! -d bash.sh -a ! -d . ] [root@localhost bash]# echo $? 1 4. 字符串測試 [ string1 string_operator string2 ] 或者 [ string_operator string ] string_operator可爲:= 兩個字符串相等 != 兩個字符串不等 -z 空串 -n 非空串 5. 數值測試 [ "number1" num_operator "number2" ] num_operator可爲: -eq 數值相等 -ne 數值不等 -gt number1 > number2 -lt number1 < number2 -le number1 <= number2 -ge number1 >= number2 例子: [root@localhost bash]# [ "100" -gt "101" ] [root@localhost bash]# echo $? 1 [root@localhost bash]# [ "100" -lt "101" ] [root@localhost bash]# echo $? 0 6. expr語法 expr arg1 operator arg2 例子:變量自增 [root@localhost bash]# COUNT=1 [root@localhost bash]# echo $COUNT 1 [root@localhost bash]# COUNT=`expr $COUNT + 1` [root@localhost bash]# echo $COUNT 2 No.018 控制流結構 1. if語句格式 if 條件1 then 執行命令1 elif 條件2 then 執行命令2 else 執行命令3 fi 2. case語句格式 case 值 in 模式1) 命令1 ;; 模式2) 命令2 ;; ...... easc 其中的「模式」能夠是 *(任意字符), ?(任意單字符), [..](範圍內任意字符) 「模式」中還能夠是使用 | (好比 str1|str2 表示str1和str2均可以) 3. for語句格式 for 變量名 in 列表 do 命令1 命令2 ...... done 4. until語句格式 until 條件 命令1 ...... done 一直執行至條件爲真時才結束,至少執行一次 5. while語句格式 while 條件 命令1 ...... done 6. 利用IFS來改變讀取內容的分隔符 7. 利用break和continue控制循環的執行 No.019 Shell函數 1. shell函數格式 函數名 () { 命令1 ...... } 或者 function 函數名 () { 命令1 ...... } 2. 引用其餘腳本中函數 . /pathname/funcfile (<點><空格><斜線><文件完整路徑名>或者<點><空格><文件相對路徑名>) 3. 函數中經過 $1, $2,......$9來獲取參數 No.020 向腳本傳遞參數 1. 使用shift依次獲取各個參數,好比 while [ $# -ne 0 ] do echo $1 # 經過shift,$1將依次表示各個參數 shift done 2. getopts語法格式 getopts operation-string variable。 No.021 屏幕輸出 1. tput 控制屏幕上的字符輸出,好比加粗字符,隱藏光標等等 2. 改變字符顏色的方法,好比 echo "<CTRL-V><ESCAPE>[40;32m" 設置背景黑色(40), 字符綠色(32) No.022 屏幕輸入 1. 輸入時進行validation check 「送進的是垃圾,出來的確定是垃圾」 No.023 調試腳本 1. shell不會對錯誤進行精肯定位,當shell打印錯誤後,須要觀察報錯的整個代碼段 2. 在腳本中利用set命令輔助調試 set -n 讀命令但不執行 set -v 顯示讀取的全部行 set -x 顯示全部命令及參數 - 表示打開; + 表示關閉;set +x 表示關閉顯示全部命令及參數 No.024 shell 嵌入命令 1. set 命令在腳本中設置腳本的運行參數 2. times命令打印shell消耗時間和運行命令消耗時間 ??? 3. type 命令查詢命令是否有效及命令類型 4. ulimit 命令設置運行在shell上的顯示限制 5. wait 命令是父進程等待子進程完成 No.025 深刻討論<< 1. 建立文本 ex. cat >> file <<end > (輸入內容) > end (輸入內容)將被追加到file中 No.026 shell工具 1. 用日期作文件名,ex. $ Myfile=`date +%Y%m%d%H%M%S` $ touch $Myfile 2. 腳本中的臨時文件名中加入進程號,能夠保證文件名惟一,並在腳本結束時刪掉文件 ex. TmpFile1=/tmp/tempfile1.$$ TmpFile2=/tmp/tempfile2.$$ rm /tmp/*.$$ 3. 經常使用信號 信號 信號名 含義 1 SIGHUP 掛起或父進程被殺死 2 SIGINT 來自鍵盤的中斷信號,一般是<CTRL-C> 3 SIGQUIT 從鍵盤退出 9 SIGKILL 無條件終止 11 SIGSEGV 段(內存)衝突 15 SIGTERM 軟件終止(缺省殺進程信號) 4. trap 捕獲信號 語法 trap "do-something" signal(s) ex. trap "" 2 3 忽略信號2和信號3,用戶不能終止該腳本 trap "commands" 2 3 若是捕捉到信號2和信號3,就執行相應的commands trap 2 3 復位信號2和3,用戶能夠終止該腳本 5. eval 對變量進行2次掃描 好比: [wangyb@localhost bash]$ VAR1="cat a.sh" [wangyb@localhost bash]$ echo $VAR1 cat a.sh [wangyb@localhost bash]$ eval echo $VAR1 cat a.sh [wangyb@localhost bash]$ eval $VAR1 #!/bin/bash TMP='HELLO' sleep 2 times 6. 獲取命令行的最後一個參數: ex. $(eval echo \$$#) 7. logger 命令記錄日誌 No.027 幾個腳本例子 # 做者經常使用的幾個腳本 No.028 運行級別腳本 1. 肯定當前的運行級別:who -r 2. 運行級別含義 運行級別0 啓動和中止整個系統 運行級別1 單用戶或管理模式 運行級別2 多用戶模式;部分網絡服務被啓動。 運行級別3 正常操做運行模式,啓動全部的網絡服務 運行級別4 用戶定義的模式,可使用該級別來定製所須要運行的服務 運行級別5 有些Unix操做系統變體叫起做爲缺省X-windows模式 運行級別6 重啓動 No.029 cgi腳本 # 感受如今應該不會有人用bash來開發web程序了吧 No.030 經常使用shell命令 1. basename : basename path 2. cat : cat optiones file -v 顯示控制字符 3. compress : compress options files -v 顯示壓縮結果 4. cp : cp options file1 file2 -i 覆蓋文件以前提示用戶確認 -p 保留權限模式和更改時間 -r 拷貝相應的目錄及其子目錄 5. diff : diff options file1 file2 -c 按照標準個數輸出 -I 忽略大小寫 6. dircmp : dircmp options directory1 directory2 -s 不顯示相同的文件 7. dirname : dirname pathname 8. du : du options directory -a 顯示每一個文件的大小,不只是整個目錄所佔用的空間 -s 只顯示總計 9. file : file filename 10. fuser : fuser options file -k 殺死全部訪問該文件或文件系統的進程 -u 顯示訪問該文件或文件系統的進程 11. head : head -number files 12. logname : logname (顯示當前使用的登錄用戶名) 13. mkdir : mkdir options directory -m 在建立目錄時按照該選項的值設置訪問權限 14. more : more options files -c 不滾屏,而是經過覆蓋來換頁 -d 在分頁處顯示提示 -n 每屏顯示n行 15. nl : nl options file -I 行號每次增長n;缺省爲1 -p 在新的一頁不從新計數 16. printf : printf format arguments 17. pwd : pwd 18. rm : rm options files -i 在刪除文件以前給出提示(安全模式) -r 刪除目錄 19. rmdir : rmdir options directory -p 若是相應的目錄爲空目錄,則刪除該目錄 20. script : script option file -a 將輸出附加在文件末尾 21. shutdown : shutdown now 22. sleep : sleep number(秒數) 23. strings : strings filename (查看二進制文件中的文本) 24. touch : touch options filename -t MMDDhhmm 建立一個具備相應月,日,時分時間戳的文件 25. tty : tty 顯示所鏈接的設備或終端 26. uname : uname options -a 顯示全部信息 -s 系統名 -v 只顯示操做系統版本或其發佈日期 27. uncompress : uncompress files 28. wait : wait processID 29. wc : wc options files -c 顯示字符數 -l 顯示行數 -w 顯示單詞數 30. whereis : whereis command_name 31. who : who options -a 顯示全部的結果 -r 顯示當前的運行級別 -s 列出用戶名及時間域
AWK學習筆記: ================================================== 1、匹配第4列包含"Brown"的行 awk '{if($4~/Brown/) print $0}' grade.dat 2、匹配第1列包含 Brown 或 Yellow的 行 awk '{if($1 ~ /Brown/ || $1 ~ /Yellow/) print $0}' grade.dat 3、匹配第3列等於"48"的行 awk '$3!="48"{print $0}' grade.dat 4、內置變量的用法: 3.1、NR: 已讀的記錄數: awk '{print $0}END{print NR}' grade.dat 3.2、NF: 瀏覽記錄的域個數: awk '{print NF" "NR" "$0}END{print FILENAME" has counts: "NF}' grade.dat NF還有一個強大的功能是將變量$pwd的值傳入awk並顯示其目錄,如:echo "bossapp/lele/into" | awk -F/ '{print $0}' 5、awk操做符 設置域變量名: awk '{name=$1;belts=$4; if(belts ~ /Yellow/) print name " is belt "belts}' grade.dat awk 'BEGIN{scolor="Yellow"}{name=$1;belts=$4; if(belts == scolor) print name " is belt "belts}' grade.dat 修改域的值:awk '{if($4 ~ /Brown/) {$4="new Brown";$6 -= 1};print $0}' grade.dat 建立新的域:awk 'BEGIN{newfield=0}{newfield=$6+$7; print $0 "\t" newfield; OFS="----"}' grade.dat 求某列值總和: awk '{total += $6;}END{print "Club student total points : "total}' grade.dat 打印某個目錄下全部文件名及其大小: ls -l | awk ' /^[^d]/ {print $8"\t"$5; total += $5} END{print "all files size is : " total}' 6、awk內置字符串函數 gsub(s,t): awk ' gsub(/48311/, a) {print $0}' grade.dat index(s,t): awk '{print index($1,"M.")}' grade.dat length(s): awk '{print length($3)}' grade.dat match(str,reg): awk '{print match($1,/^J/)}' grade.dat split(str,arr,fx): awk '{split("a/b/c/d", arr, "/"); print arr[1]}' grade.dat sub(reg, str): awk '{str="poped popo kell"; sub(/op/, "OP", str); print str}' grade.dat substr(str, i, len): awk 'BEGIN{str="poped popo kell"}END{print substr(str, 1, 5)}' grade.dat $str = "poped popo kell" echo $str | awk '{print substr($0,1,7)}' 7、awk的printf函數 echo "11" | awk '{printf "%x\n",$0}' awk '{printf "%-15s %s\n",$1,$2}' grade.dat awk '{AGE = 29; if($7 < AGE) print $0}' grade.dat df | awk '{print $3}' ================================================== sed學習筆記: ================================================== 1、匹配指定行 sed -n '2p' quote.dat 2、匹配指定範圍的行 sed -n '1,3p' quote.dat 3、匹配包含某單詞的行 sed -n '/honeysuckle/p' quote.dat 4、匹配以ing結尾的某單詞的行 sed -n '/.*ing/p' quote.dat sed -n '/.*ing/=' -e '/.*ing/p' quote.dat 5、替換文本 sed 's/night/NIGHT/' quote.dat 只替換第一次出現的night sed 's/night/NIGHT/g' quote.dat 替換全局全部的night sed 's/night/NIGHT/w sed.out' quote.dat 將修改結果輸出到文件sed.out 6、插入 sed -n 's/night/light &/p' quote.dat 在night前插入light sed 's/The/& addword/' quote.dat 在The後插入addword 7、將sed結果寫入文件 sed '1,2 w sed.out' quote.dat 將quote.dat的第一、2行寫入到sed.out文件中 8、在指定行的下一行,附加另一個文件的內容 sed '/night/r sed.out' quote.dat 9、首次匹配到某單詞後退出 sed '/music/q' quote.dat sed 's/^M//q' quote.dat 9、例:去掉路徑前的/ , 在最後加一個/ echo $PWD | sed 's/\///' | awk -F/ '{print $0"\/"}' 小結:sed 命令主要用於文本過濾及處理 ================================================== sort、uniq學習筆記 ================================================== sort: 1、按逆序排序 sort -r vid.dat 2、按指定域排序 sort -t: +1 vid.dat 3、對於數值列排序 sort -t: +2 vid.dat 先按第一個數字進行排列,再按第二個數字排列,依此類推。和字符排列同樣 sort -t: +2n vid.dat 按數值大小排序 4、從某域的第n個字符開始排序 sort -t: +2.2n vid.dat 5、指定域從1開始計數 sort -t: -k1 vid.dat 6、刪除重複的行 sort -u +5 vid.dat uniq: 7、只顯示不重複行 uniq -u a1.c 8、只顯示重複的一行 uniq -d a1.c 9、顯示覆重的行數 uniq -c a1.c 10、只按某個域進行重複排序 uniq -f2 ab.c join: 11、鏈接join join ab.c abc.c 12、左鏈接 join -a1 ab.c abc.c 13、右鏈接 join -a2 ab.c abc.c 14、顯示指定的域 join -o 1.1,1.2,2.1,2.2 ab.c abc.c 15、指定匹配域鏈接 join -j1 1 -j2 1 ab.c abc.c cut: 16、以":"爲分隔符,剪切域1 cut -d: -f1 vid.dat 17、以":"爲分隔符,剪切域一、3 cut -d: -f1,3 vid.dat 18、以":"爲分隔符,剪切域1至3 cut -d: -f1-3 vid.dat 19、以空格爲分隔符,剪切域1 cut -d" " -f1 grade.dat paste: 20、粘貼兩個域,以@爲分隔符 paste -d@ ab.c abc.c 21、把列變成行來粘貼 paste -s ab.c abc.c 22、管道輸入,"-"接受變量輸入 ls | paste a1.c - split: 23、默認按1000行分割,保存爲x[aa]--x[zz] split grade.dat 24、指定行數進行分割 split -2 grade.dat ================================================== tr學習筆記 ================================================== 1、消除重複的字符串序列 tr -s "[a-z]" < oo.dat : 消除重複的小寫字母 tr -s "[0-9]" < oo.dat : 消除重複的數字 2、刪除空行 tr -s "[\n]" < oo.dat 3、從大字轉換成小寫 tr "[A-Z]" "[a-z]" < oo.dat 4、刪除末行的控制字符 "^M" tr -s "[\r]" "[\n]" < data.f | cat -v 小結:經常使用於刪除空行,大小字替換,刪除控制字符 ==================================================Shell變量學習筆記 ==================================================1、若變量定義,則使用默認值 echo ${variable-name:-defaultValue} 2、若變量定義,則輸出錯誤信息 echo ${variable-name:?} 輸出系統錯誤信息 echo ${variable-name:?"my error message"} 輸出自定義錯誤信息 3、將變量設置成只讀 readonly variable-name 4、查看全部系統變量 env 5、系統變量必須用export命令導出 6、設置傳入變量 $0爲腳本名 $1 爲第1個參數 例如: 腳本myScript find . -name $1 -print 調用:myScript myparam 其中myparam看成參數($1)傳給腳本中的find命令 7、一些特定參數變量 $? : 顯示最後一個命令退出狀態,0爲成功,其餘值代表的錯誤 $# : 傳遞到腳本的參數的個數 $$ : 顯示腳本運行的當前進程ID號 $* : 以一個字符串顯示全部參數 $@ : 在引號中返回各個參數 ==================================================條件測試 test 學習筆記 ==================================================1、文件測試 有以下參數 -r : 可讀 -w : 可寫 -x :可執行 -d :目錄 -f :正規文件 -u :文件有suid設置 例: test -x wow [ -x wow ] 能夠將兩個測試結果進行與或操做 -a : 與 [ -w wow -a -w wow ] -o :或 [ -w wow -o -w wow ] 2、字符串測試 有五種格式 test "string" test operator "string" test "string" operator "string" [ operator "string" ] [ "string" operator "string" ] 其中,operator能夠爲: = :兩個字符串相等 != :兩個字符串不等 -z : 空串 -n : 非空串 3、數值測試 格式: test "number1" operator "number2" [ "number1" operator "number2" ] 其中,operator能夠爲: -eq :兩數相等 -ne :兩數不相等 -gt :> -lt :< -ge :>= -le :<= 4、expr的用法 4.1 expr用於數值計算 如:expr 1 + 2 expr 5 \* 3 expr 5 / 3 : 結果爲1,不保留小數位 4.2 用例:用於循環計數 loop=0 loop=`expr $loop + 1` 4.3 expr用於字符串 expr "a" = "a" : 特別須要注意的是,若是成功返回1,返回其它值爲錯誤 4.4 expr用於模式匹配 value="accounts.doc" expr $value : ".*" 統計任意字符出現的次數,也就說統計單詞的個數 expr $value : ".c" 統計c出現的 ==================================================控制結構(while、for、until loop、if then else) ==================================================1、if then else 結構 格式: if 條件1; then 語句1; elif 條件2; then 語句2; fi 例1:名字爲空,則輸出信息 #!/bin/sh echo -n "Please Enter your name:"; read NAME; if [ "$NAME" = "" ]; then echo "you havn't Enter your name!"; fi 例二、用戶輸入名字列表,腳本判斷是否包含peter #!/bin/sh echo -n "Please Enter your name:"; read NAMELIST if echo $NAMELIST | grep "peter" > inle/null 2>&1 then echo "peter is here"; else echo "peter is not here"; fi 例三、文件複製輸出檢查。自定義錯誤信息 #!/bin/sh if cp wow wow_copy >>inle/null 2>&1 then echo "複製成功!"; rm wow_copy; else echo "腳本`basename $0`發生錯誤,緣由爲: cp命令發生錯誤"; fi 例四、當前目錄測試 #!/bin/sh DIRNOW=`pwd` if [ "$DIRNOW" != "/" ] then echo "your are not at the dir of / " >&2 exit 1 fi 例五、測試傳遞到腳本的參數 #!/bin/sh if [ $# != 3 ] then echo "`basename $0`的參數個數不正確!應該爲3個" >&2 exit 1 fi echo "arg1: $1" echo "arg2: $2" echo "arg3: $3" 例六、登錄測試腳本,用戶名和密碼必須是peter/hellen--123 #!/bin/sh #設置登錄標誌 INVAIL_USER=yes INVAIL_PWD=yes #保存當前stty設置 SAVESTTY=`stty -g` echo "welcome to XX System for unix, now you will login to the system" echo "please Enter your username:" read USERNAME #設置輸入密碼時不可見 stty -echo echo "please Enter your password:" read USERPWD #恢復以前stty設置 stty echo if [ "$USERNAME" = "peter" -o "$USERNAME" = "hellen" ] then INVAIL_USER=no fi if [ "$USERPWD" = "123" ] then INVAIL_PWD=no fi if [ "$INVAIL_USER" = "no" -a "$INVAIL_PWD" = "no" ] then echo "now you have login into System" else echo "username or password is invaild, please check them and login next time" exit 1 fi 2、case 例七、一個簡單的case例子,其中配置部份能夠用"|"來做爲或命令 #!/bin/sh echo "please Enter your choose:" read ANS case $ANS in 1) echo "you have selected 1" ;; 2) echo "you have selected 2" ;; 3) echo "you have selected 3" ;; 4) echo "you have selected 4" ;; 5) echo "you have selected 5" ;; *) echo "`basename $0`發生錯誤: the choose is not between 1 and 5" >&2 esac 3、for 格式: for 變量 in 列表 do 程序體 done 其中,列表能夠是Shell命令 例八、一個最簡單的for循環 #!/bin/sh for loop in 1 2 3 4 5 do echo $loop done 例九、將ls的結果打印出來 #!/bin/sh for loop in `ls` do echo $loop done 例十、將參數打印出來 #!/bin/sh for loop in $* do echo $loop done 例十一、在for程序體中使用find,實現多文件查找 for loop do find . -name $loop -print done 例十二、統計當前目錄下的文件數目 #!/bin/sh count=0 for loop in * do count=`expr $count + 1` done echo "there is $count files" 其實用ls | wc -l 也能統計出當前目錄下文件的個數 4、until 例1三、查看root用戶是否登錄,登錄則給其發個郵件 #!/bin/sh IS_ROOT=`who | grep root` until [ "$IS_ROOT" ] do sleep 5 echo "no login" done 5、while 例1四、輸出1-10 #!/bin/sh i=0 while [ $i -lt 10 ] do echo $i i=`expr $i + 1` done 例1五、從鍵盤讀字符串,按ctrl+D結束讀入 #!/bin/sh echo -n "Enter: " while read name do echo "output: $name" done 例1六、用while循環讀取文件的每一行 #!/bin/sh while read FLINE do echo $FLINE done < data.f 例1七、以:爲分隔符,依次讀取域信息 #!/bin/sh SAVEIFS=$IFS IFS=: while read NAME DEPT do echo "$NAME\t $DEPT\t" done < name.txt IFS=$SAVEIFS 例1八、默認以空格爲域分隔符 #!/bin/sh while read f1 f2 do echo "$f1-----------$f2" done < name.txt 說明下:不管是以什麼做爲分隔符,read後面的變量個數要與域的個數相同,這樣就能夠用變量一一對應域了 例1九、每回讀兩行 #!/bin/sh while read rline1 do read rline2 echo $rline1 echo $rline2 echo "--------------------------" done < name.txt 例20、while循環和文件描述符 作文件備份,按行讀取,寫到另外一個文件 #!/bin/sh FNAME=wow FNAME_BAK=wow.bak if [ -s $FNAME ]; then #將wow描述爲輸入文件 exec 3<$FNAME #將wow描述爲輸出文件 exec 4>$FNAME_BAK while : do read LINE if [ "$?" != "0" ]; then #關閉輸入和輸出 exec 3<&- exec 4<&- exit 0 fi echo $LINE >&4 done <&3 else echo "文件不存在!" fi 6、break、continue break 2 能夠跳出兩重循環 例2一、用break(continue)跳出兩重循環 #!/bin/sh while : do echo "這是第一重循環" while : do echo "這是第二重循環" break 2 done done ==================================================自定義函數 ==================================================1、定位文件: . 文件名 這樣就能夠把文件中包含的函數當成系統函數了,直接調用便可,但只能在本終端運行,離開本終端就不行了 例2二、自定義查找函數,可查找多個文件 #!/bin/sh myfind() { if [ $# -lt 1 ]; then echo "至少有一個參數" return 1 fi for loop in "$@" do find . -name $loop -print done } 例2三、檢查名字是否全是英文 #!/bin/sh #定義檢查函數 check_name() { _PARAM_NAME=$1 _PARAM_NAME=`echo $1 | awk '{if($0 ~ /^[a-zA-Z]+$/) print "1"}'` if [ "$_PARAM_NAME" != "" ]; then return 0 else return 1 fi } #定義錯誤提示函數 name_error() { echo "$@ 包含非法字符,請確保所有是英文字母" } #開始調用 while : do echo "請輸入你的姓氏:" read FIRST_NAME if check_name $FIRST_NAME; then break else name_error $FIRST_NAME fi done while : do echo "請輸入你的名字:" read SEC_NAME if check_name $SEC_NAME; then break else name_error $SEC_NAME fi done echo "你的名字爲:$FIRST_NAME $SEC_NAME" ==================================================向腳本傳遞參數 ==================================================1、shift的做用:指向參數的位置偏移一位,從1開始 例2四、用shift實現參數位置偏移 #!/bin/sh while [ $# -ne 0 ] do echo $1 shift done 例2五、自定義大小寫轉換命令 #!/bin/sh #文件內容的大小寫轉換命令 FNAME="" OPT="no" CASEOPT="" #自定義錯誤函數 error_msg() { echo "`basename $0`: Error the conversion faild, please enter `basename $0` -help" &2 exit 1 } #大小寫轉換 l_u_case() { for LOOP in $FNAME do case $CASEOPT in lower)cat $LOOP | tr "[a-z]" "[A-Z]" >>l_rslt.dat ;; upper)cat $LOOP | tr "[a-z]" "[A-Z]" >>u_rslt.dat ;; esac done } #若不輸入參數,則報錯 if [ $# -eq 0 ] then error_msg fi #循環遍歷參數,進行處理 while [ $# -gt 0 ] do case $1 in -l)OPT="yes" CASEOPT="lower" shift ;; -u)OPT="yes" CASEOPT="upper" shift ;; -help)echo "this is help" exit 0 ;; -*) error_msg ;; *) FNAME=$1 OPT="no" shift ;; esac done #下面開始處理文件 if [ $OPT = "no" ] then if [ -f $FNAME ] then l_u_case exit 0 else echo "$FNAME is not a file ,please check it" exit 1 fi else exit 0 fi 2、getopts: 獲取用"-"開始的參數,如-fu, 其做用與-f -u 是同樣的 例2六、 #!/bin/sh while getopts :afu: OPTS do case $OPTS in a)echo "ALL" ;; f)echo "FULL" ;; u)echo "USER" ;; \?)echo "error" >&2 exit 1 ;; esac done 例2七、-u選項必須帶值,不然報錯(若要屏蔽系統錯誤,在前面加:便可); 帶入的值用變量OPTARG接收 #!/bin/sh while getopts :afu: OPTS do case $OPTS in a)echo "ALL" ;; f)echo "FULL" ;; u)echo "USER--$OPTARG" ;; \?)echo "error" exit 1 ;; esac done ==================================================一些比較雜的東西 ==================================================1、信號:系統向腳本發出的信息或命令,有以下含義: 信號 信 號 名 含 義 1 SIGHUP 掛起或父進程被殺死 2 SIGINT 來自鍵盤的中斷信號,一般是ctrl + c 3 SIGQUIT 從鍵盤退出 9 SIGKILL 無條件停止 11 SIGSEGV 段(內存衝突) 15 SIGTERM 軟件停止,默認的 2、捕捉信號 trap 例2八、當按下鍵盤停止後,用trap捕捉到信號,進行處理 #!/bin/sh trap "tp_cmd" 2 tp_cmd() { echo "hahahaha" exit 1 } loop=0 while : do loop=`expr $loop + 1` echo $loop sleep 1 done 例2九、在某一段關鍵處理過程,能夠屏蔽信號,從而保證完整性 #!/bin/sh #設置屏蔽信號 trap "echo you can't interrupt me" 1 2 3 15 ###這一段我是不但願被打斷的,不然後果很嚴重噢,除非你用kill -9 begin loop=0 while : do loop=`expr $loop + 1` echo $loop if [ "$loop" -eq "6" ] then break fi sleep 1 done ###這一段我是不但願被打斷的,不然後果很嚴重噢,除非你用kill -9 end #自定義退出函數 myexit() { echo "hahahaha" exit 1 } ##如今能夠打斷了,不要緊 trap "myexit" 1 2 3 15 while : do loop=`expr $loop + 1` echo $loop sleep 1 done 3、eval 例30、自動生成變量 #!/bin/sh loop=0 name="a" while : do loop=`expr $loop + 1` eval `echo "$name$loop=$loop"` echo $name$loop=$loop if [ "$loop" -eq "6" ] then exit 0 fi done