在日常開發中,代碼管理等使用的都是終端命令,目前我使用的是XShell。除了代碼管理(拉取、修改、提交等),版本編譯等,或多或少涉及一些shell的常用命令。而前段時間有時間學習了一下《Shell腳本學習指南 中文PDF版》,並作了筆記。該書的教程說明見http://www.linuxidc.com/Linux/2013-01/77279.htm 以下記錄的筆記一個標題可能對應的是書中的幾個章節的匯總(我覺得重要或常用的),而非單獨一章,感興趣的可以下載PDF進行詳細學習。本文還結合了菜鳥教程中的一些內容https://www.runoob.com/linux/linux-shell-variable.html
一、Shell腳本:
Shell腳本的三大特性:
簡單性:高級解釋型語言,可以簡潔的表達復雜的操作。
可移植性:使用POSIX定義的功能,使得腳本無需修改就可在不同系統上執行。
易開發:耗時短。即短時間內就可以完成一個功能強大又好用的腳本。
Shell腳本一般以#!/bin/sh開始,#!的長度限制63~1024字符,盡量不要超過64,各個系統限制有所區別。且#!前后不能有空格等其他字符,否則,執行腳本失敗"-bash: ./finduser: bin/sh: bad interpreter: No such file or directory"
#! 告訴系統其后路徑所指定的程序即是解釋此腳本文件的 Shell 程序。
簡單腳本開發步驟:以統計當前用戶數為例 $ cat > sfile //創建文件sfile
who | wc -l //統計命令
Ctrl+D //end-of-file,即退出文件
$ chmod +x sfile //賦予文件可執行權限
$ ./sfile //執行
二、Shell命令:
Shell識別三種基本命令:
內建命令:Shell本身所執行的命令,為了其必要性和效率,例:cd、 read 、test、echo、 printf等。
Shell函數:功能健全的一系列程序代碼,以Shell語言寫成,它們可以像命令那樣引用。
外部命令:由Shell的副本(新的進程)所執行的命令。以下為外部命令執行的流程圖。
1、其他常用命令:
who:當前系統上登錄用戶 echo:標准輸出 printf:與echo相比,需要在結尾使用\n換行. 基本的I/O重定向:標准輸入/輸出(<)、標准錯誤輸出(>)----默認三者在終端 tr:translate的簡寫,主要用於壓縮重復字符,刪除文件中的控制字符以及進行字符轉換操作。 -s:壓縮字符 -d:刪除字符 -t:字符替換,可以省略 格式:echo "abcddel" | tr -d "d" ====> adcel |:建立管道,program1|program2 //前一個的標准輸出為后一個的標准輸入 #:注釋
grep:查找可配合+正則表達式(略),具體參考:http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2856896.html
格式:grep "" filename
cut:切分文件,具體參考:http://www.cnblogs.com/xqzt/p/5858309.html
awk:一個強大的文本分析工具。
三、Shell變量:
不需要聲明類型,直接創建即可。以下兩個命令提供對變量的管理:
export:用於修改或打印環境變量。
readonly:只讀,使得變量不得修改。
一個簡單的例子,創建變量:
#創建變量var var="Java and Android or Shell" #顯示變量的值 echo $var echo ${var} echo _${var}_
創建變量時,等號兩邊不能存在空格(注:與其他編程語言不同)。變量的命名規則如下:
- 命名只能使用英文字母,數字和下划線,首個字符不能以數字開頭。
- 中間不能有空格,可以使用下划線(_)。
- 不能使用標點符號。
- 不能使用bash里的關鍵字(可用help命令查看保留關鍵字)。
1、POSIX Shell中其他的內置變量:顯示時都是$...
?:前一個命令的退出狀態 $:Shell進程的進程編號(process ID) 0:Shell程序的名稱 !:最近一個后台命令的進程編號. IFS:內部的字段分隔器.例如單詞分隔,一般為空格、制表符或換行. HOME:根目錄 LANG:當前locale的默認名稱 PATH:命令的查找路徑 PPID:父進程的進程編號 PWD:當前工作目錄
2、POSIX Shell的結束狀態:
0:命令成功退出 >0:在重定向或單詞展開期間 1-125:命令不成功地退出 126:命令找到了,但文件無法執行 127:命令找不到 >128:未定義 可以使用exit命令傳遞一個退出值給它的調用者,退出腳本。
四、Shell中的運算符及位置參數等:
1、替換運算符:
${var:-word}:若var存在且非null,則返回其值;否則,返回word. 用途:若變量未定義,返回默認值.
${var:=word}:若var存在且非null,則返回其值;否則,設置其為word,並返回值. 用途:若變量未定義,設置默認值.
${var:?message}:若var存在且非null,則返回其值;否則,顯示var:message,並退出當前命令或腳本. 用途:為了捕捉由於變量未定義所導致的錯誤.
${var:+word}:若var存在且非null,則返回word;否則,返回null. 用途:為測試變量的存在. 例如:若count已定義,則${count:+1}返回1.
2、模式匹配運算符:
${path#/*/} ${path%.*} 原則:#匹配的是前面(左),%匹配的是后面(右). /*/,匹配任何位於兩個斜杠之間的元素;.*,匹配點號之后接着的任何元素. ${#var}:返回var值里的字符串長度.
3、位置參數:
Shell腳本中的命令行參數;同時也表示Shell函數中的函數參數。其名稱由單個整數命名,且當這個整數大於9時,需{}。例如:
echo arg1 is $1 echo arg10 is ${10} //表示命令行的第10個參數
$#:統計參數總數. $*、$@:將所有命令行參數視為單個字符串. "$*":帶雙引號,將所有命令行參數視為一個字符串. "$@":帶雙引號,保留真正的參數值,即顯示正確的參數.【正確顯示命令行參數】 shift:截去來自列表的位置參數,由左開始.默認shift等同於shift 1,即將第一個參數移除 例: shift 10:截去第10個參數,若總數不足10個,則該語句不起作用
簡單的循環語句: for i in "$@" do echo i is $i done
4、判斷語句:
if -- then -- elif -- else --fi 寫判斷條件時,語法格式必須((...)),若以否定狀態表達,則在條件前加入!即可. 例如:
i=168 if ((i<10)) then echo "<10" elif ((i<200)) then echo "<200" else echo "fail" fi
5、test命令:用來測試文件屬性、比較字符串及數字。
格式: test [ ... ] 或[[ ... ]] 第二種格式時,表達式與[]中間必須用空白符隔開
str=5 str2=6 if test $str = $str2 then echo "===" elif [[ $str<$str2 ]] then echo "<" echo fail fi
6、case語句:每個條件用)結尾,且;;表示結束,類似java中的break,*表示默認匹配模式,類似java中的default。
case $1 in 10) echo "10" ;; 2) echo "2" ;; *) echo "other" ;; esac
7、getopts:處理輸入參數/命令行的選項。
8、$((...)):Shell中的算術運算。
9、Shell中自增的幾種格式:
- ((count++))
- let count+=1
- let count++
- count=$((count+1)) //((...)),推薦--新寫法
- count=`expr $((count+1))` //``反引號,而非單引號,原始形式
10、通配符:
?:任何的單一字符 *:任何的字符字符串 [set]:任何在set里的字符 [!set]:任何不在set里的字符
五、輸入/輸出、文件與命令執行:
1、標准輸入、輸出、標准錯誤輸出:
【0:標准輸入】 【1:標准輸出】 【2:標准錯誤輸出】 read [-r] variable:將信息讀入一個或多個Shell變量. -r:原始讀取,不將行結尾處的反斜杠解釋為續行字符.
2、重定向:
<:以只讀模式打開文件 >:以只寫模式打開文件 >>:追加 例: 2>&1,將標准錯誤輸出重定向到標准輸出.
3、Shell中的.bat文件就是一個可執行文件,雙擊該文件即可彈出終端運行,執行其中的命令。類似刷機文件update_all.bat
例: set update="update_test" echo %update% pause //執行完命令后暫停,提示用戶按任意鍵退出,而非直接退出.
4、隱藏文件(.file),只是個習慣用法,在用戶層面的軟件上它是這樣的,但核心程序(kernel)並不認為開頭帶有點號的文件與其他文件有不同。
5、嵌套命令:
for i in $(cd bin;echo vartest) //找到bin目錄下的vartest文件 do diff -c bin/$i $i #第二個$i 表示當前目錄下的文件$i done | more
6、head命令:顯示文件的前n行
head -n 10 file //顯示名為file的文件的前10行
7、set命令:
主要是顯示系統中已經存在的shell變量,以及設置shell變量的新變量值。set命令不能夠定義新的shell變量。如果要定義新的變量,可以使用declare命令以 變量名=值 的格式進行定義即可。
-a 標示已修改的變量,以供輸出至環境變量。 -b 使被中止的后台程序立刻回報執行狀態。 -C 轉向所產生的文件無法覆蓋已存在的文件。 -d Shell預設會用雜湊表記憶使用過的指令,以加速指令的執行。使用-d參數可取消。 -e 若指令傳回值不等於0,則立即退出shell。 -f 取消使用通配符。 -h 自動記錄函數的所在位置。 -H Shell 可利用"!"加<指令編號>的方式來執行history中記錄的指令。 -k 指令所給的參數都會被視為此指令的環境變量。 -l 記錄for循環的變量名稱。 -m 使用監視模式。 -n 只讀取指令,而不實際執行。 -p 啟動優先順序模式。 -P 啟動-P參數后,執行指令時,會以實際的文件或目錄來取代符號連接。 -t 執行完隨后的指令,即退出shell。 -u 當執行時使用到未定義過的變量,則顯示錯誤信息。 -v 顯示shell所讀取的輸入值。 -x 執行指令后,會先顯示該指令及所下的參數。 +<參數> 取消某個set曾啟動的參數。
執行腳本時,可以使用以下命令跟蹤:
set -x :打開執行跟蹤的功能,這會使得Shell顯示每個被執行的命令,並在前面加上“+”
set +x :關閉跟蹤
六、總結:
關於Shell的常用命令及基本用法已經介紹完,其他的文件處理、進程等章節並未在本文顯示,感興趣的可閱讀PDF,后續根據需要可能會進行補充。