本文來自於哥們對《LINUX與UNIX Shell編程指南》一書的寫寫畫畫,併合成了本身當初一些疑問點所致,僅限學習使用,同時向原做者致敬。 原書請見 http://product.china-pub.com/632 shell 文件安全與權限 使用find 和xargs 後臺執行命令 文件名置換 shell輸入與輸出 命令執行順序 文本過濾正則表達式介紹 grep 家族 awk 介紹 sed用法介紹 合併與分割 tr用法 登錄環境 登錄環境 環境和shell變量 引號 基礎shell編程 shell腳本介紹 條件測試 控制流結構 shell 函數 向腳本傳遞參數 建立屏幕輸出 建立屏幕輸入 調試腳本 shell嵌入命令 高級shell編程 深刻討論<< shell工具 幾個腳本例子 運行級別腳本 cgi腳本 經常使用shell命令
對於文件屬主來講,在只有讀權限位被置位的狀況下,仍然能夠經過文件重定向的方法向該文件寫入。?? 可否刪除一個文件還依賴於該文件所在目錄權限位的設置。 r--r----- 同組用戶權限,通常來講,是文件屬主所在的缺省組。 chmod用戶權限位的表示方式:比較短的絕對模式(每個權限位用一個八進制數來表明 0400)和長一些的符號模式: s 文件屬主和組set-ID t 粘性位 l 給文件加鎖,使其餘用戶沒法訪問。 在列文件或目錄時,有時會遇到"t"位。「t」表明了粘性位。若是在一個目錄上出現"t"位,這就意味着該目錄中的文件只有其屬主才能夠刪除,即便某個同組用戶具備和屬主同等的權限。不過有的系統在這一規則上並不十分嚴格。 若是在文件列表時看到"t",那麼這就意味着該腳本或程序在執行時會被放在交換區(虛存)。不過因爲當今的內存價格如此之低,大可沒必要理會文件的"t"的使用。 $ chmod u+x o-w myfile 能夠經過-R 選項連同子目錄下的文件一塊兒設置。 目錄: 目錄的讀權限位意味着能夠列出其中的內容。寫權限位意味着能夠在該目錄中建立文件,若是不但願其餘用戶在你的目錄中建立文件,能夠取消相應的寫權限位。執行權限位則意味着搜索和訪問該目錄。 若是把同組用戶或其餘用戶針對某一目錄的權限設置爲--x,那麼他們將沒法列出該目錄中的文件。若是該目錄中有一個執行位置位的腳本或程序,只要用戶知道它的路徑和文件名,仍然能夠執行它。用戶不可以進入該目錄並不妨礙他的執行。 目錄的權限將會覆蓋該目錄中文件的權限。 suid/guid(有些系統供應商不容許實現或者忽略這一設置,由於它會帶來安全性風險。) suid意味着若是某個用戶對屬於本身的shell腳本設置了這種權限,那麼其餘用戶在執行這一腳本時也會具備其屬主的相應權限。因而,若是根用戶的某一個腳本設置了這樣的權限,那麼其餘普通用戶在執行它的期間也一樣具備根用戶的權限。一樣的原則也適用於guid,執行相應腳本的用戶將具備該文件所屬用戶組中用戶的權限。 有至關一些UNIX命令也設置了suid和guid。若是想找出這些命令,能夠進入/bin或者/sbin目錄,執行以下的命令: $ ls -l | grep '^...s' $ ls -l | grep '^...s..s' 一旦設置了這一位,一個s將會出如今x的位置上。記住:在設置suid或guid的同時,相應的執行權限位必需要被設置。例如,若是但願設置guid,那麼必需要讓該用戶組具備執行權限。 設置suid命令:$ chmod 4741 logit $ chmod u+s filename 在查找設置了suid的文件時,沒準會看到具備這樣權限的文件:rwSr-xr-x,其中S爲大寫。它表示相應的執行權限位並未被設置,這是一種沒有什麼用處的suid設置,能夠忽略它的存在。 chown和chgrp: 在改變一個文件的全部權時,相應的suid也將被清除,這是出於安全性的考慮。只有文件的屬主和系統管理員能夠改變文件的全部權。 $ chmod -R -h owner file -h 選項意味着在改變符號連接文件的屬主時不影響該連接所指向的目標文件。 若是你但願知道本身屬於哪些用戶組,能夠使用以下命令:$ group $ id 爲了找出其餘用戶所屬於的組,能夠用以下的命令:$ group xxx umask 在已經登陸以後,能夠按照我的的偏好使用umask命令來改變文件建立的缺省權限。相應的改變直到退出該shell或使用另外的umask命令以前一直有效。 通常來講,umask命令是在/etc/profile文件中設置的,每一個用戶在登陸時都會引用這個文件。因此若是但願改變全部用戶的umask,能夠在該文件中加入相應的條目。若是但願永久性地設置本身的umask值,那麼就把它放在本身$HOME目錄下的.profile或.bash_profile文件中。 對於文件來講,這一數字的最大值分別爲6,系統不容許你在建立一個文本文件時就賦予它執行權限,必須在建立後用chmod命令增長這一權限。目錄則容許設置執行權限,這樣針對目錄來講,umask中各個數字最大能夠到7. $ umask nnn umask 值002所對應的文件和目錄建立缺省權限分別爲664和775。 若是想知曉當前的umask值,能夠使用 $ umask 符號連接: 軟鏈接實際上就是一個指向文件的指針。 $ ln [-s] source_path target_path 其中的路徑能夠是目錄也能夠是文件。 無論是否在同一個文件系統中,均可以建立連接。在建立連接的時候,不要忘記在原有目錄設置執行權限。連接一旦建立,連接目錄將具備權限777或rwxrwxrwx,可是實際的原有文件的權限並未改變。 小結: 是否適用設置了suid的腳本徹底取決於你本身。若是適用的話,必定要確保可以監控它的使用,並且不要以跟用戶身份設置suid。
有時可能須要在系統中查找某一特徵的文件(例如文件權限、文件屬主、文件長度、文件類型等)。這樣作可能有不少緣由。可能出於安全性的考慮,或是通常性的系統管理任務,或許只是爲了找出一個不知保存在什麼地方的文件。 即便系統中含有網絡文件系統(NFS),find命令在該文件系統中一樣有效,只要你具備相應的權限。 find pathname -options [ -print -exec -ok ] -exec相應命令的形式爲'command' {} \; 注意{} 和 \; 之間的空格。 find命令選項: -name -perm 按照文件權限來查找文件 -prune 使用這一選項能夠使find命令不在當前指定的目錄中查找,若是同時使用了-depth選項,那麼 -prune選項將被find命令忽略? -user 按照文件屬主來查找文件 -group -mtime -n +n -n表示文件更改時間距如今n天之內,+n表示文件更改時間距如今n天之前 -atime -ctime -nogroup 查找無有效所屬組的文件,即該文件所屬的組在/etc/groups中不存在 -nouser 在/etc/passwd中不存在 -newer file1 !file2 查找更改時間比文件file1新但比文件file2舊的文件 -type b,d,c,p,l(符號連接),f -size n[c] 查找文件長度爲n塊的文件,帶有c時表示文件長度以字節計。 -depth 在查找文件時,首先查找當前目錄中的文件,而後再在其子目錄中查找。? -fstype 查找位於某一類型文件系統中的文件,這些文件系統類型一般能夠在配置文件/etc/fstab中找到,該配置文件中包含了本系統中有關文件系統的信息。 -mount 在查找文件時不跨越文件系統mount點 -follow 若是find命令遇到符號連接文件,就跟蹤至連接所指向的文件。 -cpio 對匹配的文件使用cpio命令,將這些文件備份至磁帶設備中。 -name 使用某種文件模式來匹配文件,記住要用引號將文件名模式引發來。 $ find ~ -name "*.txt" -print 在當前目錄及子目錄中查找: $ find . -name "[A-Z]*" -print $ find . -name "[a-z][a-z][0-9][0-9].txt" -print -perm 最好使用八進制的權限表示法 $ find . -perm 755 -print $ find . -perm -007 -print 權限前加- 表示包含 -prune? 能夠使用-prune選項來指出須要忽略目錄。在使用-prune選項時要小心,由於若是你同時使用了-depth選項,那麼-prune選項將會被find命令忽略 $ find /apps -name "/apps/bin" -prune -o -print 不進入目錄 -user,-nouser $ find ~ -user yali -print $ find /etc -user uucp -print -group,-nogroup 其餘的: $ find . -newer age.awk !-newer belts.awk -exec ls -l {} \; touch -t 05042140 dstamp ! 指定更改時間 -type 查找初目錄之外的全部類型的文件 $ find . ! -type d -print 文件系統的大小使用塊來計量 $find . -size +10 -print -depth $find / -name 'con.file' -depth -print 首先匹配全部的文件,而後進入子目錄查找 (先內部,再目錄;默認爲先目錄,後深刻) -mount $ find . -name '*.xc' -mount -print 不進入其餘系統 -cpio 用來向磁帶設備備份文件或從中恢復文件。 $ find etc home apps -depth -print | cpio -ivcdC65536 -o /dev/rmt0 之因此使用相對路徑,是由於從磁帶中恢復這些文件的時候,能夠選擇恢復文件的路徑。 cpio命令使用了C65536選項,本能夠使用B選項,不過這樣每塊的大小隻有512字節,而使用了C65536選項後,塊的大小編程了64K字節 find命令只輸出從當前路徑起的相對路徑和文件名 $ find logs -type f -mtime +5 -exec rm {} \; 示例: $ find ~ -print $ find -type f -perm 4755 -print $ find . -type d -print -mount | sort xargs 有些系統對可以傳遞給exec的命令長度有限制,這樣在find命令運行幾分鐘以後就會出現溢出錯誤。錯誤信息一般是「參數列太長」或「參數列溢出」。這就是xargs命令的用處所在,特別是與find命令一塊兒使用。 xargs每次只獲取一部分文件而不是所有。 在有些系統中,使用-exec選項會爲處理每個匹配到的文件而發起一個相應的繼承,並不是將匹配到的文件所有做爲參數一次執行;這樣在有些狀況下就會出現進程過多,系統性能降低的問題,於是效率不高;而使用xargs命令則只有一個進程。 每一次獲取參數的數目都會根據該命令的選項及系統內核中相應的可調參數來肯定。 內存信息轉儲文件(core dump)
對於密集訪問磁盤的進程,你可能但願它可以在天天的非負荷高峯時間段運行。 幾種措施: 一、設置crontab文件、並用它來提交做業。 二、使用at命令來提交做業 三、在後臺提交做業 四、使用nohup命令提交做用 crontab 系統管理員是經過cron.deny和cron.allow這兩個文件來禁止或容許用戶擁有本身的contab文件 當使用crontab運行shell腳本時,要由用戶來給出腳本的絕對路徑,設置相應的環境變量。 要保證在shell腳本中提供全部必要的路徑和環境變量,除了一些自動設置的全局變量。 若是cron不能運行相應的腳本,用戶將會受到一個郵件說明其中的緣由。(沒有輸出是否也發送通知?) crontab -u 用戶名 -r 刪除crontab文件 初建: 編輯$HOME目錄下的.profile文件,加入:EDITOR=vi;export EDITOR /bin/echo `date` >/dev/console 在有些系統中,用tty1來表示控制檯 crontab davecron 將文件提交給cron進程,新建立文件的一個副本已經被放在/var/spool/cron目錄中,文件名就是用戶名dave crontab -e 在保存cron文件時,cron會對其進行必要的完整性檢查。若是其中的某個域出現了超出容許範圍的值,它會提示你。 最好在每個條目之上加入一條註釋,這樣就能夠知道它的功能、運行時間,更爲重要的是,知道這是哪位用戶的做業。 at命令: 一旦一個做業被提交,at命令將會保留全部當前的環境變量,包括路徑,不象crontab,只提供缺省的環境。該做業的全部輸出都將以電子郵件的形式發送給用戶,除非你對其輸出進行了重定向,絕大多數狀況下是重定向到某個文件中。 經過/etc/目錄下的at.allow,at.deny文件來控制哪些用戶能夠使用at命令,哪些不能夠。 $ at [ -f script ] [ -m -l -r ] [ time ] [ date ] -l 列出當前全部等待運行的做業,atg命令具備相同的做用。 -r 清楚做業。爲了清楚某個做業,還要提供相應的做業標識(ID),有些unix變體只接受atrm做爲清除命令 -m 做業完成後給用戶發郵件 time at命令的時間格式很是靈活;能夠是H,HH.HHMM,HH:MM或者H:M 還能夠使用a.m p.m date 日期格式能夠是月份數或日期數,還能夠識別today tomorrow這樣的詞 at 兩種格式: 一、命令行 $ at 21:10 at> fine / -name "passwd" -print at>(ctrl +D) at 6.45am MAY 12 at 11.10pm at now + 1 hour at 9am tomorrow at 15:00 May 24 at now + 10 minutes 二、shell腳本 $ at 3.00pm tomorrow -f /apps/bin/db_table.sh $ echo find /etc -name 'passwd' -print | at now +1 minute 當提交一個做業後,它就被拷貝到/var/spool/at目錄中,準備在要求的時間運行 三、清除一個做業 atrm [job no] at -r [job no] & 須要用戶交互的命令不要放在後臺執行,由於這樣你的機器就會在那裏傻等。 command > out.file 2>&1 & 當使用ps命令列出進程時,它沒法肯定該進程是運行在前臺仍是後臺。 nohup: nohup就是不掛起的意思(no hang up) nohup command & 在缺省狀況下該做業的全部輸出都被重定向到一個名爲nohup.out的文件中,除非另外執行了輸出文件: nohup command > myout.file 2>&1 常規來講,在nohup的狀況下,其會自動將報錯記錄到文件中 不加文件的話,在當前執行目錄下生成nohuo.out $ cat >yali xxxxx
shell提供了一套完整的字符串模式匹配規則,或者稱之爲元字符。還能夠使用字符類型來匹配文件名。 [!...]匹配非 當shell遇到上述元字符時,就會把他們當作特殊字符,而不是文件名中的普通字符,這樣用戶就能夠用他們來匹配響應的文件名。 $ ls -al | grep ^d $ ls log.[!0-9]* 使用元字符能夠大大減小你在查找文件名上的工做量。這是一種很是有效的模式匹配方法,在後面的章節中,咱們還將討論正則表達式時候對文本處理中所涉及到的元字符。
標準輸入:缺省爲鍵盤 或者 指定一個文件做爲輸入 echo: 能夠顯示文本行或變量,或者把字符串輸入到文件。 echo 命令有許多功能,其中最經常使用的是下面幾個: \c 不換行 \f 進紙 \t 跳格 \n 換行 $ echo "what is your name : \c" $ read name 還能夠用echo命令輸出轉義符以及變量。 $ echo "\007 your home directory is $HOME, you are connected on `tty`" 若是是linux系統,必須使用-n選項來禁止echo命令輸出後換行。必須使用-e選項才能使轉義符生效。 $ echo "\"/dev/rmt0\"" read: 從鍵盤或文件的某一行文本中讀入信息,並將其賦給一個變量。若是隻指定了一個變量,那麼read將會把全部的輸入賦給該變量,直至遇到第一個文件結束符或回車。 若是給出多個變量,shell將用空格做爲變量之間的分隔符。 若是輸入文本域過長,shell將全部的超長部分賦予最後一個變量。 若是擔憂用戶會對此感到迷惑,而已採用每個read語句只給一個變量賦值的方法。 cat: cat 是一個簡單而通用的命令,能夠用它來顯示文件內容,建立文件,還能夠用它來顯示控制字符。在使用cat命令時要注意,它不會在文件分頁處停下來;它會一下顯示完整個文件。若是但願每次顯示一頁,能夠使用more命令或把cat命令的輸出經過管道傳遞到另一個具備分頁功能的命令中。 $ cat myfile | pg -v 顯示控制字符 $ cat > myfile this is great若是不加文件名稱,則會在終端回顯這些內容。 DOS機器拷貝過來的文件都會包含控制符 管道: 把一個命令的輸出傳遞給另外一個命令做爲輸入 $ who | awk '{print $1"\t"$2}' | sed s'/\/dev\///g' $ sort myfile | lp 先對一個文件進行排序,而後經過管道輸出到打印機。 tee: 把輸出的一個副本輸送到標準輸出,另外一個副本拷貝到響應文件中。 tee -a files -a表示追加到文件末尾。 $ find etc usr/local home -depth -print | cpio -ovC65536 -O /dev/rmt/0n | tee -a tape.log $ echo "xxxxxxxxx" | tee /dev/console 標準輸入、輸出和錯誤: 在shell中執行命令的時候,每一個進程都和三個打開的文件相聯繫,並使用文件描述符來引用這些文件。 系統中實際上有12個文件描述符,0、一、2是標準輸入、輸出和錯誤。能夠任意使用文件描述符3到9 command < filename >filename2 以filename文件做爲標準輸入,以filename2文件做爲標準輸出 command << delimiter 從標準輸入中讀入,直至遇到delimiter分界符 command < &m 把文件描述符m做爲標準輸入 command > &m 把標準輸出重定向到文件描述符m中 command < &- 關閉標準輸入 重定向標準輸出: 在使用sort命令的時候(或其餘含有類似輸入文件參數的命令),重定向符號必定要離開sort命令兩個空格,不然該命令會把它當作輸入文件。 $ cat passwd | awk -F: '{print $1}' | sort 1>sort.out 若是想建立一個長度爲0的空文件,能夠用 $ >myfile 重定向標準輸入: $ sort < name.txt $ cat >>myfile <hello $HOME > xxxx > MYDAY exec: exec命令能夠用來替代當前shell;換句話說,並無啓動子shell。使用這一命令時任何現有環境都將會被清除,並從新啓動一個shell。它的通常形式爲: exec command exec命令的一個常見用法就是在用戶的.profile最後執行時,用它來執行一些用於加強安全性的腳本。若是用戶的輸入無效,該shell將被關閉,而後從新回到登錄提示符。exec還經常被用來經過文件描述符打開文件, 記住,exec在對文件描述符進行操做的時候(也只有在這個時候),它不會覆蓋你當前的shell、 使用文件描述符: 能夠使用exec命令經過文件描述符打開和關閉文件。 exec 4 < &0 0 < stock.txt read line1 read line2 exec 0 < &4 echo $line1 echo $line2 該腳本第一行把文件描述符4指定爲標準輸入,而後打開stock.txt文件。接下來兩行的做用是讀入了兩行文本。 接着做爲標準輸入的文件描述符4被關閉。最後line1和line2兩個變量所含有的內容被回顯到屏幕上。 小結: 這裏沒有涉及的就是文件描述符的應用(3~9)。要想應用這些文件描述符,就必定會涉及循環方法,在後面講到循環方法的時候,咱們會再次回過頭來說述有關文件描述符的問題。
一、命令執行順序 二、命令組合 && || shell 提供了在當前shell或子shell中執行一組命令的方法,即便用()和{} 當前shell中執行一組命令: (命令1;命令2;...) 只有在{}中全部命令的輸出做爲一個總體被重定向時,其中的命令才被放到子shell中執行,不然在當前shell中執行。 {命令1;命令2;...} $ comet month_end || ( echo "Hello, guess what! Comet did not work" | mail dave;exit ) 若是隻使用了命令分隔符而沒有把它們組合在一塊兒,shell將直接執行最後一個命令exit
當從一個文件或命令輸出中抽取或過濾文本時,能夠使用正則表達式(RE),正則表達式是一些特殊或不很特殊的字符串模式的集合。 這些規則由一些特殊字符或進行模式匹配操做時使用的元字符組成。也能夠使用規則字符做爲模式中的一部分進行搜尋。 系統自帶的全部大的文本過濾工具在某種模式下都支持正則表達式的使用,而且還包括一些擴展的元字符集。 .容許匹配ASCII集中任意字符,或爲字母,或爲數字 匹配空行 ^$ 下列字符能夠認爲是特殊字符: $.'"*[]^|0\+? 使用[]匹配特定字符串或者字符串集,能夠用逗號將括弧內要匹配的不一樣字符串分開,但並不強制要求這樣作(一些系統提倡在複雜的表達式中使用逗號),這樣作能夠增長模式的可讀性。 使用\{\}匹配模式結果出現的次數 [.*0]0以前或以後加任意字符? [000*]000或更多個 '"Device"' 單詞device [^.*$]匹配任意行 在shell編程中,一段好的腳本與完美的腳本間的差異之一,就是要熟知正則表達式並學會使用它們。相比較起來,用一個命令抽取一段文本比用三四個命令得出一樣的結果要節省許多時間。
相信grep是UNIX和LINUX中使用最普遍的命令之一。grep(全局正則表達式版本)容許對文本文件進行模式查找。若是找到匹配模式,grep打印包含模式的全部行。 grep支持基本正則表達式,也支持其擴展集。 grep有三種變型,即: Grep:標準grep命令 Egrep:擴展grep,支持基本及擴展的正則表達式,但不支持\q模式範圍的應用,與之相對應的一些更加規範的模式,這裏也不討論。 Fgrep:快速grep。容許查找字符串而不是一個模式。不要誤解fast,實際上它與grep速度至關。 實際上應該只有一個grep命令,但不幸的是沒有一種簡單形式可以統一處理grep的三種變形,將之合而爲一,並保持grep單模式處理時的速度。GNU grep 雖然在融合三種變形上邁進了一大步,但仍不能區分元字符的基本集和擴展集。 grep [選項] 基本正則表達式 [ 文件 ] 雙引號引用: 在grep命令中輸入字符串參數時,最好將其用雙引號括起來。這樣作有兩個緣由,一是以防被誤解爲shell命令,二是能夠用來查找多個單詞組成的字符串。 在調用變量時,也應該使用雙引號,grep "$MYVAR" 文件名,若是不這樣,將沒有返回結果。 在調用模式匹配時,應使用單引號。 grep選項: -c 只輸出匹配行的計數 -i 不區分大小寫 -h 查詢多文件時不顯示文件名 -l 查詢多文件時只輸出包含匹配字符的文件名 -n 顯示匹配行及行號 -s 不顯示不存在或無匹配文本的錯誤信息 -v 顯示不包含匹配文本的全部行。 精確匹配: $ grep "48" data.f表示點擊tab鍵 使用grep抽取精確匹配的一種更有效方式是在抽取字符串後加 \> $ grep '48\>' data.f grep和正則表達式: 使用正則表達式最好用單引號括起來,這樣能夠防止grep中使用的專有模式與一些shell命令的特殊方式相混淆 使用grep匹配「與」或者「或」模式 grep命令加-E參數,這一擴展容許使用擴展模式匹配。 $ grep -E '219|216' data.f 查詢格式化文件名: 系統中對文本文件有其標準的命名格式。通常最多六個小寫字符,後跟句點,接着是兩個大寫字符 類名: grep容許使用國際字符模式匹配或匹配模式的類名形式 [[:upper:]] [[:lower:]] [[:digit:]] [[:alnum:]] [[:space:]] 空格或tab鍵 [[:alpha:]] = [a-zA-Z] 大多數系統管理員稱/dev/null爲比特池(系統池),不要緊,能夠將之當作一個無底洞,有勁沒有出,永遠也不會填滿。 $ echo $STR | grep "yali" egrep 表明 expression或extended grep,適狀況而定。egrep接受全部的正則表達式,egrep的一個顯著特性是能夠以一個文件做爲保存的字符串,而後將之傳給egrep做爲參數,爲此使用-f開關 $ egrep -f grepstrings data.f $ who | egrep -v '^(matty|pauline)' $ egrep '(shutdown|reboot)(s)?' * 括號不須要轉義
awk在文本瀏覽和數據的熟練使用上性能優異 awk是全部shell過濾工具中最難掌握的 a、複雜的語法 b、含義不明確的錯誤提示信息 awk是一種自解釋的編程語言,之因此要在shell中使用awk是由於awk自己是學習的好例子,但結合awk與其餘工具,諸如grep和sed,將會使shell編程更加容易。 本書僅注重於講述使用awk執行行操做及怎樣從文本文件和字符串中抽取信息 nawk和gawk,他們擴展了awk的文本特性。 完整的awk腳本一般用來格式化文本文件中的信息。 調用awk: 一、awk [-F field-separator] 'commands' input-file(s) 二、將全部awk命令插入一個文件,並使awk程序可執行,而後用awk命令解釋器做爲腳本的首行,以便經過鍵入腳本名稱來調用它。 三、將全部的awk命令插入一個單獨文件,而後調用 awk -f awk-script-file input-files(s) awk腳本: awk腳本由各類操做和模式組成。 模式與動做: 模式部分決定動做語句什麼時候觸發及觸發事件。處理即對數據進行的操做。若是省略模式部分,動做將時刻保持執行狀態。 模式能夠是任何條件語句或複合語句或正則表達式。模式包含兩個特殊字段,BEGIN和END.使用BEGIN語句設置計數和打印頭,END打印輸出文本總數和結尾狀態標誌。若是不特別指明模式,awk老是匹配或打印行數。 實際動做在大括號{}內指明,動做大多用來打印,可是還有些更長的代碼諸如if和循環語句及循環退出結構。若是不指明採起動做,awk將打印出全部瀏覽出來的記錄。 使用標準輸入: 先對awk腳本的輸入方法簡要減小一下。實際上任何腳本都是從標準輸入中接受輸入的。例如: a、awk腳本 $ belts.awk grade_student.txt b、重定向:$ belts.awk < grade2.txt c、管道方法 grage2.txt | belts.awk 打印單獨記錄: 不要忘了加逗號以分割域 $ awk '{print $1,$4}' grade.txt awk錯誤信息提示: awk將試圖打印錯誤行,但因爲大部分命令都只在一行,所以幫助不大。 在碰到awk錯誤時,可相應查找: a、確保整個awk命令用單引號括起來 b、確保命令內全部引號成對出現 c、確保用花括號括起動做語句,用圓括號括起條件語句。 d、可能忘記使用花括號,也許你認爲沒有必要,但awk不這樣認爲,將按之解釋語法。 awk條件操做:/Green/ 元字符: awk中正則表達式匹配操做中常常用到的字符:\^$.[]|()*+? 這裏有兩個字符僅適用於awk而不適用於grep或sed + ? 條件操做符: < <= == != >= ~ !~ 模式匹配: {if($4~/brown/)print} 匹配記錄找到時,若是不特別聲明,awk缺省打印整條記錄 精確匹配: 爲精確匹配48,使用等號==,並用單引號括起條件,例如$3 == "48" $ awk '$3=="48"{print $0}' grade.txt 設置大小寫: 爲查詢大小寫信息,可以使用[]符號 '/[Gg]reen/' 任意字符: 使用.句點 '/^...a/' 或關係匹配: 使用豎線時,語句必須用圓括號括起來 $ awk '$0~/(Yellow|Brown)/' grade.txt 複合模式或者複合操做符用於造成複雜的邏輯操做,複雜程度取決於編程者本人。有必要了解的是,複合表達式即爲模式間經過使用下述各表達式互相結合起來的表達式:&& || ! $awk '{if($1=="P" && $4=="Yellow")print $0}' grade.txt awk內置變量: awk有許多內置變量用來設置環境信息,這些變量能夠被改變。 ARGC 命令行參數個數 ARGV 命令行參數排列: ARGV[n] 0爲awk自己,1,2標識後面引用的文件位置 ENVIRON 支持隊列中系統環境變量的使用 ENVIRON["EDITOR"]="Vi" FILENAME awk瀏覽的文件名 FNR 瀏覽文件的記錄數 FS 設置輸入域分隔符,等價於命令行-F選項 NF 瀏覽記錄的域個數 NR 已讀的記錄數 OFS 輸出域分隔符,缺省爲空格 ORS 輸出記錄分隔符 RS 控制記錄分隔符,缺省爲新行 \n $ echo $PWD | awk -F/ '{print $NF}' awk操做符 基本表達式能夠劃分爲數字型、字符串型、變量性、域及數組元素 賦值操做符 = += *= /= %= ^= 條件表達操做符 並、與、非 || && ! 匹配操做符,包括匹配和不匹配 ~ !~ 關係操做符 < <= == != >= 算術操做符 + - * / % ^ 前綴和後綴 ++ -- 設置輸入域到域變量名 $ awk '{name=$1;belts=$4;if(belts ~/Yellow/)print "name is belt"belts}' grade.txt 修改數值域取值: 要記住實際輸入文件是不可修改的,修改的只是保存在緩存裏的awk副本。 $ awk '{if($1 == "M.Tansley")$6=$6-1;print $1,$6,$7}' grade.txt 修改文本域: 記住字符串要使用雙引號"",並用圓括號括起整個語法 $ awk '{if($1=="J.Troll")($1="J.L.Troll");print $1}' grade.txt 只顯示修改記錄: $ awk '{if($1=="J.Troll"){$1="J.L.Troll";print $1}}' grade.txt 建立新的輸出域: '{$8=$7-$6}' 新生成的$8默認會寫到標準輸出 增長列值: $ awk '(tot+=6);END{print "Club student total points :" tot}' grade.txt $ awk '{(tot+=$6)};END{print "Club student total points :" tot}' $ ls -l | awk '/^[^d]/{print $9"\t"$5}{tot+=$5}END{PRINT "total KB:"TOT}' 內置的字符串函數: gsub(r,s) 在整個$0中用s替代r gsub(r,s,t) 在整個t中用s替代r index(s,t) 返回s中字符串t的第一位置 length(s) 返回s長度 match(s,r) 測試s是否包含匹配r的字符串,返回字符排列數,沒有返回0 split(s,a,fs) 在fs上將s分紅序列a,返回字符串數組元素格式,下標從1開始。 sprint(fmt,exp) 返回經fmt格式化後的exp sub(r,s) 用$0最左邊最長的字串代替s,該字串被r匹配,只替換匹配的第一次出現 substr(s,p) 返回字符串s中從p開始的後綴部分 substr(s,p,n) 返回字符串s中從p開始長度爲n的後綴部分,若是給定長度遠大約字符串長度,awk將從起始位置返回全部字符。 $ STR="mydoc.txt" $ echo $STR | awk '{print substr($STR,7)}' 字符串屏蔽序列: awk 使用的屏蔽序列 \b 退格鍵 \f 走紙換頁 \n 新行 \r 回車鍵 \t tab鍵 \ddd 八進制值 \c 任意其餘特殊字符,例如\\爲反斜線符號 $ awk 'BEGIN{print "\nMay\nMay \104\141\171"}' \104爲D的八進制ASCII碼,\141爲a的八進制ASCII碼,等等 awk printf修飾符 - 左對齊 Width 域的步長,用0表示0步長 .prec 最大字符串長度,或小數點右邊的位數 awk printf格式 %c ASCII 字符 %d 整數 %e 浮點數,科學計數法 %f 浮點數,例如(123.44) %g awk決定使用哪一種浮點數轉換e或者f %o 八進制數 %s 字符串 %x 十六進制 $ echo "65" | awk '{printf "%c\n",$0}' 缺省狀況下printf不作換行動做 浮點數轉換 $ awk 'BEGIN{printf "%f\n",999}' 999.000000 轉換後被加了六個小數點 格式化輸出 $ awk '{printf "%-15s %s\n",$1,$3}' grade.txt 向一行awk命令傳值 $ awk '{if($5 < AGE)print $0}' AGE=10 grade.txt 傳入環境變量: user=$LOGNAME awk腳本文件: 好處:命令長、沒必要反覆輸入、能夠增長註釋 給全部awk程序假如awk擴展名是一種好習慣 #!/bin/awk -f next 的使用? 數組使用前,沒必要定義,也沒必要指定數組元素個數。常用循環來訪問數組。 For (element in array) print array[element] $ arraytest.awk /dev/null 在打印語句末尾有一個\符號,用來通知awk(或相關腳本)命令持續到下一行,當輸入一個很長的命令,而且想分行輸入時能夠使用這種方法。
sed是一個非交互性文本流編輯器。它編輯文件或標準輸入導出的文本拷貝。標準輸入多是來自鍵盤、文件重定向、字符串或變量,或者是一個管道的文本。 sed一次性處理全部改變,於是變得頗有效,對用戶來說,最重要的是節省了時間。 內容包含: 抽取域 匹配正則表達式 比較域 增長、附加、替換 基本的sed命令和一行腳本 不管命令是什麼,sed並不與初始化文件打交道,它操做的只是一個拷貝,而後全部的改動若是沒有重定向到一個文件,將輸出到屏幕。 由於sed是一個非交互性編輯器,必須經過行號或正則表達式制定要改變的文本行。 sed怎樣讀取數據: sed從文件的一個文本行或從標準輸入的幾種格式中讀取數據,將之拷貝到一個編輯緩衝區,而後讀命令行或腳本的第一條命令,並使用這些命令查找模式或定位行號編輯它。重複此過程直到命令結束。 調用sed 調用sed有三種方式: 在命令行鍵入命令 將sed命令插入腳本文件,而後調用sed 將sed命令插入腳本文件,並使sed腳本可執行。 sed [選項] sed命令 輸入文件 無論使用shell命令行方式或腳本文件形式,若是沒有指定輸入文件,sed從標準輸入中接收輸入,通常是鍵盤或重定向結果。 sed選項: n 不打印,p命令打印編輯行 c 下一命令是編輯命令,使用多項編輯時加入此選項 f 調用sed腳本文件使用 使用sed在文件中查詢文本的方式: 有兩種方式定位文本: 一、使用行號或行號範圍 二、使用正則表達式 x x爲一行號 x,y 行範圍 /pattern/ /pattern/pattern/ 查詢包含兩個模式的行 /pattern/,x 在給定行號上查詢包含模式的行 x,/parttern/ 經過行號和模式查詢匹配行 從第一個匹配到第二個匹配 x,y 查詢不包含制定行號x和y的行? sed 編輯命令 p 打印匹配行 = 顯示文件行號 a\ 在定位行號後附加新文本信息 i\ 在定位行號後插入新文本信息 d 刪除定位行 c\ 用新文本替換定位文本 s 使用替換模式替換相應模式 r 從另外一個文件中讀文本 w 寫文本到一個文件 q 第一個模式匹配完成後退出或當即退出 l 顯示與八進制ASCII代碼等價的控制字符 顯示每行數據的控制符 {}在定位行執行的命令組 n 從另外一個文件中讀文本下一行,並附加在下一行 g s/ */,/g y y/abc/ABC/將把全部小寫的a轉換成A n 延續到下一輸入行;容許跨行的模式匹配語句 $ sed -n '2p' quote.txt $ sed -n '/Neave/'p quote.txt $ sed -n '4,/The/'p quote.txt 只在第四行匹配The $ sed -n '/\$/'p quote.txt 匹配元字符 $ sed -n '1,$p' quote.txt $即最後一行 $ sed -n '/.*ing/'p quote.txt $ sed -n -e '/pattern/p' -e '/pattern/=' 打印行號 若是不指定文本放置文職,sed缺省放在每一行後面。附加文本時不能指定範圍,只容許一個地址模式。 地址指定一個模式或行號,定位新文本附件位置,斜劃線表明換行。若是不加,sed假定這是附加命令結尾。 #! /bin/sed -f 修改命令將在匹配模式空間的指定行用新文本加以替代。 能夠對統一腳本中的相同文件進行修改、附加、插入三種動做匹配和混合操做。 刪除文本:地址能夠是行的範圍或模式。 替換文本: 替換命令用替換模式替換指定模式 [address[,address]] s/pattern-to-find/replacement-pattern/[g p w n] g 缺省狀況下只替換第一次出現模式,使用g替換全局 p 輸出 w 文件名 輸出定向到文件 $sed 's/splendid/SPLENDID/w sed.out' quote.txt 使用替換修改字符串 若是要附加或修改一個字符串,能夠使用 & 命令,& 命令保存發現模式以便從新調用它,而後把它放在替換字符串裏面 $ sed -n 's/played/from hock &/p' quote.txt 從文本中讀文本: sed容許從另外一個文件中讀文本,並將其文本附加在當前文件,注意所讀的文件名須要用單引號括起來 $ sed '/company./r sedex.txt' quote.txt 匹配後退出: 在模式匹配首次出現後退出sed,以便執行其餘處理腳本。 $ sed '/.a.*/q' quote.txt 顯示文件中的控制字符(非打印字符): cat -v filename 便可識別 sed 格式: [address,[address]]l l即爲列表 \033表明退格鍵,OP爲F1鍵值 各系統控制字符鍵值可能不一樣,主要取決於其映射方式(例如 使用 terminfo 或 terncap) 在文本文件中插入控制字符F1鍵 vi ctrl + v F1 (顯示OP) esc 產生控制字符^M ctrl+v 釋放v,按住^鍵 釋放兩個鍵,按鍵 若是使用sed對文件進行過濾,最好將問題分紅幾步,分步執行,且邊執行邊測試結果。經驗告訴咱們,這是執行一個複雜任務的最有效方式。 高級編輯命令: 因爲各類各樣的緣由,好比用戶但願在某個條件下腳本中的某個命令被執行,或者但願模式空間獲得保留以便下一次的處理,都有可能使得sed在處理文件的時候不按照正常的流程來進行。這個時候,sed設置了一些高級命令來知足用戶的要求。 sed命令: + g:[address[,address]]g 將hold space中的內容拷貝到pattern space中,原來pattern space裏的內容清除 + G:[address[,address]]G 將hold space中的內容append到pattern space\n後 + h:[address[,address]]h 將pattern space中的內容拷貝到hold space中,原來的hold space裏的內容被清除 + H:[address[,address]]H 將pattern space中的內容append到hold space\n後 + d:[address[,address]]d 刪除pattern中的全部行,並讀入下一新行到pattern中 + D:[address[,address]]D 刪除multiline pattern中的第一行,不讀入下一行 PS:不管是使用G、g仍是H、h,它們都是將hold space裏面的內容「copy」到pattern space中或者將pattern space中的內容「copy」到hold space中。
有幾種工具用來處理文本文件分類、合併和分割操做: sort uniq cut paste split sort 實際上,在使用其餘unix工具時,已假定工做文件已經被分過類。不管如何,分類文件比不分類文件看起來更有意義。 sort選項: sort -cmu -o output_file [other options] +pos1 +pos2 input_files -c 測試文件是否已經分類 -m 合併兩個分類文件 -u 刪除多有複製行 -o 存儲sort結果的輸出文件名 -b 使用域進行分類時,忽略第一個空格 -n 指定分類是域上的數字分類 -t 域分隔符;用非空格或tab鍵分隔域?? -r 對分類次序或比較求逆 +n n爲域號,使用此域號開始分類 n n爲域號,在分類比較時忽略此域,通常與+n一塊兒使用 post1 傳遞到m,n。m爲域號,n爲開始分類字符數;例如 4,6即以第5域分類,從第7個字符開始 缺省狀況下,sort認爲一個空格或一系列空格爲分隔符,要假如其餘方式分隔,使用-t選項 缺省時sort將整個行排序,指定域號的狀況例外 $ sort -t: +1 video.txt $ sort -t: +3n video,txt $ sort -t: -k4 video.txt 從1開始 $ sort -t: -k4 -k1 video.txt 使用-n選項指定不適用哪一個分類鍵進行查詢 sort +0 -2 +3 以域0分類,忽略域2,而後再使用域3分類 $ sort -t: +1.2 video.txt 若是使用head或者tail時想省略顯示行數,缺省時顯示10行 將兩個分類文件合併: 將文本合併前,他們必須已被分類。合併文件可用於事務處理和任何種類的修改操做 $ sort -m sorted_file1 sorted_file2 uniq用法: uniq用來從一個文本文件中去除或禁止重複行。通常uniq假定文件已分類,而且結果正確。 sort的惟一性選項去除全部的重複行,而uniq命令並非這樣作。重複行是什麼?在uniq裏即持續不斷重複出現的行,中間不夾雜任何其餘文本。 uniq -u d c -f input-file output-file -u 只顯示不重複行 -d 只顯示有重複數據行,每種重複行只顯示其中一行 -c 打印每一重複行出現次數 -f n爲數字,前n個域被忽略 一些系統不識別-f選項,這時替代使用-n 從1開始 join用法: join 用來未來自兩個分類文本文件的行連在一塊兒 這裏有點像修改一個主文件,使之包含兩個文件裏的共同元素。 文本文件中的域一般由空格或tab鍵分隔,一些系統要求使用join時文件域要少於20,爲公平起見,若是域大於20,應使用DBMS系統。 join [options] input-file1 input-file2 選項列表: an n爲一數字,用於鏈接時從文件n中顯示不匹配行。 o n.m n爲文件號,m爲域號。1.3表示只顯示文件1第三個域,每一個n,m必須用逗號分隔 j n m n爲文件號,m爲域號。使用其餘域作鏈接域 t 域分隔符。 缺省join刪除或去除鏈接鍵的第二次重複出現,這裏即爲名字域 $join -j1 4 -j 2 2 per pers2 cut用法 cut用來從標準輸入或文本文件中剪切列或域。剪切文本能夠將之粘貼到一個文本文件。 cut [options] file1 file2 -c list 指定剪切字符數 -f field 指定剪切域數 -d 指定與空格和tab鍵不一樣的域分隔符 -c 用來指定剪切範圍 -c1,5-7 剪切第一個字符,而後是第5~7個字符 -c1-50 剪切前50個字符 -f 格式與-c相同 -f1,5 剪切第1域,第5域 -f1,10-12 使用-c選項指定精確剪切數目。這種方法須要確切知道開始以及結束字符,使用在固定長度的域或文件名上 paste用法: 粘貼兩個不一樣來源的數據時,首先須要將其分類,並確保兩個文件函數相同。 paste將按行將不一樣問津啊行信息放在一行。缺省狀況下,paste鏈接時,用空格或tab鍵分隔新行中不一樣文本,除非指定-d選項,它將成爲域分隔符 paste -d -s file1 file2 -s 將每一個文件合併成行而不是按行粘貼? - 使用標準輸入,例如ls | paste 即只在一列上顯示輸出 paste命令管道輸入: paste命令還有一個頗有用的選項-,即對每個-,從標準輸入讀一次數據,使用空格作域分隔符,以一個4列格式顯示 $ls | paste -d" " - - - - xx xx xx xx xx xx split用法: split用來將大文件分隔成小文件 split -output_file-size input-filename output-filename 每一個文件格式爲x[aa]~x[zz]
tr用來從標準輸入中經過替換或刪除操做進行字符轉換。 tr剛執行時,字符串1中的字符被映射到字符串2中的字符,而後轉換操做開始。 內容: 大小寫轉換 去除控制字符 刪除空行 tr -c -d -s ["string1_to_translate_from"] ["string2_to_translate_to"] file -c 用字符串1中字符集的補集替換此字符集,要求字符集爲ASCII -d 刪除字符串1中的全部輸入字符 -s 刪除全部重複出現字符序列,只保留第一個;即將重複出現字符串壓縮爲一個字符串。 字符範圍: 使用tr時,能夠指定字符串列表或範圍做爲造成字符串的模式。指定字符串1或字符串2內容時,只能使用單字符或字符串範圍或列表。 [a-z] [A-Z] [0-9] /octal 一個三位的八進制數,對應有效的ASCII字符 [O*n]表示字符O重複出現指定次數n 大部分tr變種支持字符類和速記控制字符。字符類格式爲[:class],包含數字、希臘字母、空行、小寫、大些、cntrl鍵、空格、點記符、圖形等 tr中特定控制字符的不一樣表達方式: 速記符、含義、八進制方式 \a Ctrl-G鈴聲 \007 \b Ctrl-H退格符 \010 \f Ctrl-L走行換頁 \014 \n Ctrl-J新行 \012 \r Ctrl-M回車 \015 \t Ctrl-I tab鍵 \011 \v Ctrl-X \030 $ tr -s "[a-z]" < oops.txt $ cat oops.txt | tr -s "[a-z]" 去除重複字符 刪除空行: $ tr -s "[\012]" < plane.txt $ tr -s ["\n"] < plane.txt 大寫到小寫: $ tr "[a-z]" "[A-Z]" $ tr "[:lower:]" "[:upper:]" 刪除指定字符: 須要結合使用-c和-s選項完成此功能 $ tr -cs "[a-z][A-Z]" "[\012*]" < diary.txt 轉換控制字符: tr的第一個功能就是轉換控制字符,特別是從dos向UNIX下載文件時,忘記設置ftp關於回車換行轉換的選項時更是如此。 tr -s "[\015\032]" "\n" < stat.tmp ^八進制爲136,^M爲015,tab鍵爲011 ^Z爲032 $ tr "[0*4]" "*" < hdisk.txt 替換字符串爲*號 tr主要用於字符轉換或者抽取控制字符。本章全部功能均可以用sed來完成,但有些人寧願使用tr,由於tr更加快捷、容易。
登錄系統時,在進入命令提示符前,系統要作兩個工做。鍵入用戶名和密碼後,系統檢查是否爲有效用戶,爲此需查詢/et/passwd文件。若是登錄名正確而且密碼有效,開始下一步過程,即登錄環境。 內容範圍: 登錄過程 文件/etc/passwd $HOME.profile 定製 $HOME.profile 登錄成功後,系統執行兩個環境設置文件,第一個是/etc/profile,第二個是.profile,位於用戶跟目錄下。 系統還會處理其餘的初始化文件,這裏只涉及profile文件 /etc/profile 此文件包含: 全局或局部環境變量 PATH信息 終端設置 安全命令 日期信息或放棄操做信息 設置全局環境變量便於用戶及其進程和應用訪問它,PATH定位包含可執行文件,庫文件及通常文本文件的目錄位置,便於用戶快速訪問。 終端設置使系統獲知用戶終端的通常特性。 安全命令包含文件建立模式或敏感區域的雙登錄提示?。 日期信息是一個文本文件,保存用戶登錄時即將發生事件的記錄或放棄登錄的信息文件。 用戶的$HOME.profile 通常來講建立帳戶時,一個profile文件的基本框架即隨之建立。不要忘了在.profile文件中能夠經過設置相關條目以不一樣的值或使用uset命令來覆蓋/etc/profile文件中的設置。若是願意,能夠定製用戶本身的.profile文件。 $ PS1="`hostname`>" 設置輔助命令提示符 $PS2="`echo "\251"`:" @ ASCII代碼八進制數 stty用法: stty用於設置終端特性。stty -a 設置終端時遇到的一個最廣泛的問題時退格鍵不起做用。本機stty命令中^?即爲退格鍵,使用可能會退格並刪除前一個字符 stty name character $ stty erase '\^H' 在vim下,Ctrl+V,釋放V鍵,再按下H鍵 經常使用stty命令以下: intr ^C 終止進程 echo 打開echo功能 -echo 關閉echo功能? eof ^D 文件尾;註銷 kill ^Y 刪除一行 start ^Q 滾動屏幕文本 stop ^S 中止滾動屏幕文本 stty -g 此選項容許以可讀格式保存stty現有設置,便於之後重置回stty 若是linux中使用轉義字符,使用 echo -e stty命令能夠與終端、打印機、調制解調器打交道,功能十分豐富。使用stty時要慎重,不要使用已經使用的鍵或無效值。 建立.logout文件: 使用Bourne shell 與其餘shell不一樣,其肯定是不包含.logout文件。此文件保存有執行exit命令時,在進程終止前執行的命令。 可是經過使用trap命令,Bxx shell 也能夠建立本身的.logout文件。 trap "$HOME/.logout" 0
shell變量能夠保存諸如路徑名、文件名或者一個數字這樣的變量名。shell將其中任何設置都看作文本字符串。 兩種變量:本地和環境 內容涵蓋: shell變量 環境變量 變量替換 導出變量 特定變量 向腳本傳遞信息 在系統命令行下使用位置參數 使用變量時,若是用花括號將之括起來,能夠防止shell誤解變量值。 $yali=111 ${yali=111} 變量設置時的不一樣模式: xxx=value xxx+value 若是設置了xxx,則重設其值? xxx:?value 若是未設置xxx,顯示未定義用戶錯誤信息?? xxx?value 若是未設置xxx,顯示系統錯誤信息?? xxx:=value 若是未設置xxx,設置其值 xxx:-value 同上,可是取值並不設置到xxx,能夠被替換 echo $yali ;echo ${yali} unset yali 使用set命令顯示全部本地定義的shell變量 將變量並排能夠使變量結合在一塊兒 $echo ${FIRST}${SURNAME} ${var:-value} 若是設置了變量值,則使用它,不然取新值 設置只讀變量 $ xxx=value $ readonly xxx 環境變量: 環境變量用於全部用戶進程(常常爲子進程)。登錄進程成爲父進程。shell中執行的用戶進程均稱爲子進程。 環境變量能夠在命令行中設置,但用戶註銷時即丟失,所以最好在.profile文件中定義 xxx=value; export xxx; 使用env便可查看全部的環境變量 嵌入shell變量 brourneshell中預留的環境變量名,這些變量名不能用做其餘用途。一般在/etc/profile中創建這些嵌入的環境變量,但也不徹底是,這取決於用戶本身。 CDPATH $CDPATH=:/home/dave/bin:/usr/local/bin;export CDPATH EXIINIT EXINIT變量保存使用vi編輯器時的初始化選項。例如,使用vi時,要顯示行號,且在第10個空格加入tab鍵,命令爲: $ EXINIT='set nu tab=10';export EXINIT; HOME IFS IFS用做shell指定的缺省域分隔符。原理上將域分隔符能夠是任意字符,但缺省一般爲空格、新行或tab鍵。IFS在分隔文件或變量中各域時頗有用。 $ export IFS=: $ echo $PATH /sbin /bin /usr/sbin /usr/bin /root/bin 要設置其返回初始設置: $ ifs=;export IFS; LOGNAME MAIL:缺省爲/var/spool/mail/MAILCHECK:缺省每60s檢查新郵件 MAILPATH: 若是有多個郵箱要用到MAILPATH,此變量設置將覆蓋MAIL設置 $MAILPATH=/var/spool/dave:/var/spoll/admin;export MAILPATH PATH $ PATH=$PATH:/$HOME/BIN; export PATH; PS1 基本提示符包含shell提示符,缺省對超級用戶是#,其餘爲$ PS2 附屬提示符,缺省爲符號> SHELL 保存缺省shell TERMINFO 終端初始化變量保存終端配置文件的位置,一般在/usr/lib/terminfo或/usr/share/terminfo TERM TERM變量保存終端類型。設置TERM使應用獲知終端對屏幕和鍵盤響應的控制序列類型,經常使用的用vt100,vt200,vt220-8 TZ 時區變量保存時區值,只有系統管理員才能夠更改此設置。 $echo $TZ GMT2EDT 返回值代表正在使用格林威治標準時間,與GMT時差爲0,並做EDT保存。 其餘環境變量: 還有一些預留的環境變量。其餘系統或命令行應用將用到他們。如下是最經常使用的一些,注意這些值均未有缺省設置,必須顯示說明。 EDITOR PWD PAGER 保存屏幕翻頁命令,如pg、more,在查看man文本時用到此功能。 MANPATH 保存系統上man文本的目錄 LPDEST PRINTER 保存缺省打印機名,用於打印做業時指定打印機名 $ LPDEST=hp3si-systems set -a 指明全部變量直接被導出 將變量導出到子進程: 不能夠將變量從子進程導出到父進程,然而經過重定向就可作到這一點。 位置變量參數: 四種變量: 本地 環境 還有兩種變量被稱爲是特殊變量,由於它們是隻讀的。這兩種變量即爲位置變量和特定變量參數 參數數目能夠任意多,但只有前9個能夠被訪問,使用shift命令能夠改變這個限制 特定變量參數: 腳本運行時的一些相關控制信息,這就是特定變量的由來,共7個 $# 傳遞到腳本的參數個數 $* 以一個單字符串顯示全部向腳本傳遞的參數。與位置變量不一樣,此選項參數能夠超過9個。 $$ 腳本運行的當前進程ID號 $!後臺運行的最後一個進程的進程ID號? $@ 與$#相同,但使用時加引號,並在引號中返回每一個參數? $- 顯示shell使用的當前選項,與set命令功能相同? $? 顯示最後命令的退出狀態。 特定變量加強了腳本的功能並提供了傳遞到腳本的參數的更多信息。
在腳本中執行變量替換時最容易犯的一個錯誤就是因爲引用錯誤。 內容範圍: 引用的必要性 雙引、單引和反引號 使用反斜線實現屏蔽 腳本中執行行操做時,shell將對腳本設置予以解釋。要採起一種方法防止shell這樣作,即便用引用號,包括各式引用或使用反斜線。 shell應用類型: ""雙引號 ''單引號 ``反引號 \反斜線 使用雙引號可引用除字符$、`、\外的任意字符或字符串 單引號會忽略任何引用值 反引號用於設置系統命令的輸出到變量。 $ date +%A" the "%e" of "%B" "%Y 反斜線: 若是下一個字符有特殊含義,反斜線防止shell誤解其含義,即屏蔽其特殊含義。即:& * + ^ $ ` " | ? $echo $$ $echo \$$ $echo "This is a copyright \251 sign" $expr 12 \* 12 在echo命令中假如元字符,必須用反斜線起屏蔽做用,例如\$19.99
內容範圍: 使用shell腳本的緣由 shell腳本基本元素 shell腳本運行方式 緣由: shell腳本在處理自動循環或大的任務方面可節省大量的時間,且功能強大。 建立一個腳本,在使用一系列系統命令的同時,能夠使用變量、條件、算術和循環快速建立腳本以完成相應工做。 shell的可遷移性不成問題,可是系統間命令的可遷移性存在差異。 若是寫一段腳本,其執行結果與預想的不一樣,沒必要着急。不管多難以想象的結果,記住先把它保存起來,這是修改的基礎。這裏要說的意思是不要懼怕對待新事物,不然將不能樹立信息,學起來會更加困難。 腳本: #!/bin/sh # name:cleanup # this is a general cleanup script xxxx
寫腳本時,有時要判斷字符串是否相等,可能還要檢查文件狀態或是數字測試。基於這些測試才能作進一步動做。 Test命令用於測試字符串,文件狀態和數字。if then else 內容範圍: 對文件、字符串和數字使用test命令 對數字和字符串使用expr命令 expr命令測試和執行數值輸出。使用最後退出狀態命令$?可測知test和expr,兩者均以0表示正確,1表示返回錯誤。 測試文件狀態: test condition [condition] 使用方括號時,要注意在條件兩邊加上空格。 文件狀態測試: -d 目錄 -f 正規文件 -L 符號連接 -r 可讀 -s 文件長度大於0、非空 -w 可寫 -u 文件有suid位設置 -x 可執行 $ [ -w scores.txt ] $ test -w scores.txt 測試時使用邏輯操做符: -a 邏輯與 -o 邏輯或 ! 邏輯否 $ [ -w results.txt -a -w scores.txt ] 字符串測試: 字符串測試時錯誤捕獲很重要的一部分,特別在測試用戶輸入或比較變量時尤其重要。 字符串測試有5種格式: test "string" test string_operator "string" test "string" string_operator "string" [ string_operator string ] [ string string_operator string ] string_operator = 相等 != 不等 -z 空串 -n 非空串 沒有規定在設置變量時必定要用雙引號,但在進行字符串比較時必須這樣作。 $ [ "$TYPE" != "$TYPE2" ] 測試數值: [ "number" numberic_operator "number" ] operator: -eq -ne -gt -lt -le -ge $ [ "$NUMBER" -eq "130" ] $ [ "990" -le "995" -a "123" -gt "33" ] expr用法: expr命令通常用於整數值,但也可用於字符串 expr argument operator argument expr 10 + 10 expr 10 \* 10 數值測試: 能夠用expr測試一個數,若是試圖計算非整數,將返回錯誤。 $ expr $VALUE + 10 > /dev/null 2>&1 $ echo $? expr也能夠返回其自身的退出狀態,但其與系統最後退出命令恰好相反,成功返回1,任何其餘值爲無效或錯誤。 模式匹配: 使用expr經過指定冒號選項計算字符串中字符數。 expr length "this is a test" expr substr "this is a test" 3 5 expr index "sarasara" a 在expr中能夠使用字符串匹配操做 $expr $VALUE : '\(.*\).doc' accounts
全部功能腳本必須有能力進行判斷,也必須有能力基於必定條件處理相關命令。 內容範圍: 退出狀態 while for 和 until loops 循環 if then else 語句 腳本中動做 菜單 退出狀態: 主要有4中退出狀態 最後命令退出狀態$? 控制次序命令 $$,|| 其他兩種是處理shell腳本或shell退出及相應狀態退出狀態或函數返回碼 若是不加參數,exit將試圖返回上一個命令返回值。 shell會提供一些列命令聲明語句等補救措施來幫助你在命令成功或失敗時,或須要處理一個命令清單時採起正確的動做。 循環和流控制 流控制: if then else 語句提供條件測試 case語句容許匹配模式、單詞或值,一旦模式或值匹配,就能夠基於這個匹配條件做其餘聲明 循環: 循環或跳轉是一系列命令的重複執行過程。 for循環,每次處理依次列表內信息,直至循環耗盡。 until循環 while循環 if then else if 條件1 then 命令1 elif 條件2 then 命令2 else 命令三 fi 使用if語句時,必須將then部分放在新行,不然會產生錯誤。若是要不分行,必須使用命令分隔符。 if 條件; then 命令 fi if grep 'Dave\>' data.file >/dev/null 2>&1 then xxx else xxx fi 若是匹配成功,grep返回0,if部分爲真? 決定腳本是否爲交互模式: 有時須要知道腳本運行時交互模式(終端模式)仍是非交互模式(cron或at)。腳本也許須要這個信息以決定從哪裏取得輸入以及輸出到哪裏,使用test命令並帶有-r選項很容易確認這一點,若是test返回值爲1,則爲交互模式。 if [ -t ];then xxx fi null:命令用法 if xxx then xxx else: fi if [ "$ANS" = "y" ] || [ "$ANS" = "Y" ] …… case語句 case 值 in 模式1) 命令1 …… ;; 模式2) 命令2 …… ;; *) …… ;; esac 模式部分可能包含元字符,與在命令行文件擴展名例子中使用過的匹配模式類型相同,即: * 任意字符 ? 任意單字符 [..]類或返回中任意字符 對匹配模式使用| for循環 for 變量名 in 列表 do 命令1 命令2…… done in列表能夠包含替換、字符串和文件名 for loop in 1 2 3 4 5 for loop in "orange red blue grey" for loop in `ls` 在for循環中省去in列表選項時,它將接受命令行位置參數做爲參數。實際上即指明: for params in "$@" for params in "$*" $ XXXXX < < MAYDAY $ MAYDAY DOC文檔 until循環: until 條件 命令1 …… done 條件可爲任意測試條件,測試發生在循環末尾,所以循環至少執行一次。 while循環: while 命令 do 命令1 命令2 done 使用while循環讀入鍵盤輸入: while read FILM do xxx done 直至輸入< Ctrl+D >終止 while read LINE do echo $LINE done < names.txt 使用IFS讀文件: 輸出時要去冒號域分隔符,可以使用變量IFS while read NAME DEPT ID xxx case $LINE in \#$);; while循環和文件描述符: while循環用到了空命令:,這是一個死循環,由於null永遠返回真。 exec 3 < &- 使用break和continue控制循環: 若是在兩層循環內,用break 2 恰好跳出整個循環 菜單選擇: 若是用戶選擇無效,應發出警報並帶有警告信息。 echo "\007 the bell ring" tput clear
shell容許將一組命令集或語句造成一個可用塊,這些塊成爲shell函數 內容範圍: 定義函數 在腳本中使用函數 在函數文件中使用函數 函數舉例 函數有兩個部分組成: 函數標題 函數體 標題名必須惟一,若是不是,將會混淆結果,由於腳本在查看調用腳本前將首先搜索函數調用相應的shell 函數名() { 命令1 …… } function 函數名(){ } 能夠將函數看作是腳本中的一段代碼,可是有一個主要區別。執行函數時,它保留當前shell和內存信息。此外,若是執行或調用一個腳本文件中的另外一段代碼,將建立一個單獨的shell,於是去除全部原腳本中定義的存在變量? 全部函數在使用前必須定義。這意味着必須將函數放在腳本開始部分。 向函數傳遞參數: 向函數傳遞參數就像在通常腳本中使用特殊變量 $1,$2,...$9同樣 在shell中使用函數: 文件名應包含語句 #!/bin/sh 使用set命令查看全部定義的函數 echo -n 不打印換行 echo -e 反饋控制字符 echo -e -n "$@" 在菜單中進行選擇時,最麻煩的工做是必須在選擇後鍵入回車鍵,或顯示「press any key to continue」。能夠使用dd命令解決不鍵入回車符以發送擊鍵序列的問題。 dd命令經常使用於對磁帶或通常的磁帶解壓任務中出現的數據問題提出質疑和轉換,但也可用於建立定長文件。 dd if:/dev/zero of=myfine count=512 bs=2048 建立長度爲1兆的文件myfine dd命令能夠翻譯鍵盤輸入,可被用來接受多個字符。這裏若是隻要一個字符,dd命令須要刪除換行字符,這與用戶點擊回車鍵相對應。dd只送回車前一個字符。再輸入前必須使用stty命令將終端設置成未加工模式,並在dd執行前保存配置,在dd完成後恢復終端設置。 SAVESTTY=`stty -g` stty cbreak dd if=/dev/tty bs=1 count=1 2>/dev/null stty -cbreak stty $SAVEDTTY 函數中用_開頭的表示臨時變量,果然是臨時的嗎? nl 列出文件行號 echo $@ | tr '[a-z]' '[A-Z]' 獲取字符串長度,length($0) wc會將兩端的空格也做爲字符串的一部分,而awk在讀取鍵盤時缺省截取字符串末尾處空格。 測試函數時,首先將其做爲代碼測試,當結果滿意時,再將其轉換爲函數。 函數調用: 從源文件中調用函數和使用腳本中的函數 定位文件不僅針對於函數,也包含組成配置文件的全局變量。 建立可用和可重用的腳本頗有意義,能夠使主腳本變短,結構清晰。
能夠建立一個usage語句,須要時可通知用戶怎樣以適當的調用參數調用腳本或函數。 內容涵蓋: shift getopts shift和getopts例子 任何UNIX或LINUX命令均接受通常格式: 命令 選項 文件 選項部分最多可包含12個不一樣的值。? 幸運的是shell提供shift命令以幫助偏移選項,使用shift能夠去除只使用$1到$9傳遞參數的限制。 shift 每次將參數位置向左偏移一位 命令行輸入的最後一個參數: eval echo \$$# 使用shift命令: shift `expr $#-2` shift 在接收多個參數時,顯得力不從心,這就須要用到getopts命令 getopts getopts能夠編寫腳本,使控制多個命令行參數更加容易。getopts用於造成命令行處理標準形式。原則上講,腳本應具備確認帶有多個選項的命令文件標準格式的能力。 getopts腳本實例: while getopts ahfgv OPTION do case $OPTION in a)ALL=true echo "ALL is $ALL" ;; …… esac done getopts option_string variable 若是未發現匹配字符,變量被設置爲? 使用getopts指定變量取值 有時有必要在腳本中指定命令行選項取值。 getopts ahfvc: OPTION 使用選項取值時,必須使用變量OPTARG保存該值 \?) $usage statement getopts的一種功能是運行後臺腳本。這樣能夠使用戶加入選項,指定不一樣的磁帶設備以備份數據 while getopts :luv 最前面的冒號「:」用於指定getopts工做於silent mode 經常使用命令行選項和含義列表: -a 擴展 -c 計數、拷貝 -d 目錄、設備 -e 執行 -f 文件名、強制 -h 幫助 -i 忽略狀態 -l 註冊文件 -o 完整輸出 -q 退出 -p 路徑 -v 顯示方式或版本
用戶能夠使用shell腳本建立交互性的、專業性強的屏幕輸出。要實現這一點,系統上須要一個彩色監視器和tput命令。 內容範圍: tput命令 使用轉義序列和產生控制碼 使用顏色 tput至今爲止最好的是GNU tput。tput使用文件/etc/terminfo或/etc/termcap,這樣就能夠在腳本中使用終端支持的大部分命令了。 雖然tput不識別顏色設置,可是能夠使用控制字符實現這一點。 tput 在使用tput以前,須要在腳本或命令行中使用tput命令初始化終端。 $tput init tput產生三種不一樣的輸出:字符型、數字型和布爾型(真/假) 字符串輸出: 大部分經常使用字符串: bel 警鈴 blink 閃爍模式 bold 粗體 civis 隱藏光標 clear 清屏 cnorm 不隱藏光標 cup 移動光標到屏幕位置(x,y) el 清除到行尾 ell 清除到行首 smso 啓動突出模式 rmso 中止突出模式 sc 保存當前光標位置 rc 恢復光標到最後保存位置 sgr0 正常屏幕 rev 逆轉視圖 數字輸出: 大部分經常使用數字輸出: cols 列數目 it tab設置寬度 lines 屏幕行數 布爾輸出: 兩種布爾輸出: chts 光標不可見 hs 具備狀態行 tput用法: 能夠取得全部tput名字輸出,將其保存爲更有意義的變量名 variable_name=`tput name` 使用布爾輸出: if `tput hs` 全部控制字符均以一個轉義序列開始。一般轉義鍵後緊跟字符[。而後實際序列打開和關閉某終端屬性。 發送一轉義序列以關閉光標 linux/bsd echo -e "\033[?251" System V echo "\033[?251" General method echo "[?251" \033爲轉義鍵取值 要反饋一個 @ 字符 echo "@" echo -e "\100" 命令clear表示清屏併發送光標到屏幕左上角,此位置通常也稱爲home 對於嵌入在文本中的任何控制字符,不要試圖剪切和粘貼,由於這樣會失去其特殊含義。 例如,要插入控制字符,打開光標,方法以下: echo 'hit thekey then [?25h' 即先擊,再擊退格鍵,確保這不是一個仿真器。而後加入一小段腳本將之打開和關閉。 光標位置: 能夠用tput將光標放在屏幕任意位置 cup r c r爲從上至下屏幕行數,c爲穿過屏幕列數 屏幕中間顯示: LEN=`echo $STR | wc -c` COLS=`tput cols` NEW_COL=`expr \($COLS-$LEN\)/2` xy 10 $NEW_COL 查找終端屬性: 使用tput訪問terminfo,顯示前面提到過的tpur命令下的一些終端轉義碼 查看終端定義文件的完整列表: $ infocmp $TERM 在腳本中使用功能鍵 使用cat命令能夠查看發送的任意特殊鍵控制序列(F1,上箭頭等),鍵入cat -v,飯後按任意控制鍵,回車,在下一行就能夠知道終端發送了什麼功能鍵。結束後按退出。 F1(^[OP]) F2([OQ]),上箭頭[^[[A] 使用顏色: 對域使用顏色能夠使數據輸入屏幕看起來更加專業。下面將使用的顏色是ANSI標準顏色,並非全部顏色都適合於全部系統。下面列出了大部分經常使用顏色。 一、前景色: 數字 顏色 30 黑色 31 紅色 32 綠色 33 黃(或棕)色 34 藍色 35 紫色 36 青色 37 白(或灰)色 二、背景色 40 黑色 41 紅色 42 綠色 43 黃(或棕)色 44 青色 45 藍色 46 青色 47 白(或灰)色[background_number;foreground_number m 產生顏色: 產生顏色須要在echo語句中嵌入控制字符 要產生一個黑色背景加綠色前景色 linux/bsd echo -e "\033[40;32m" System V echo "\033[40;32m" Generic method echo "[40;32m" 將顏色設置與echo語句放在一個case語句裏,而後將之編成一個函數,這樣作最好。 做者終端的缺省屏幕顏色是黑色和白色。可是若是要用黑色背景加綠色前景,可插入一個echo語句,同時將之放入用戶.profile文件中。 trap命令,用戶忽略信號2,3,15 這樣將防止用戶試圖跳出菜單。 使用tput命令能夠加強應用外觀及腳本的控制。顏色設置能夠增長應用的專業性。能夠使用和讀取控制字符來增長腳本的靈活性,特別是對用戶擊鍵輸入操做更是如此。
屏幕輸入或數據輸入時接受輸入(這裏是鍵盤)並驗證其有效的能力。若是有效,接受它,若是無效,放棄該輸入。 內容範圍: 驗證有效輸入 增長、刪除、修改和查看記錄 修改腳本的工做文件。 運行腳本應具備一些菜單選項,與任務或模塊相鏈接或包含在文件裏與菜單腳本相關的一些列函數相鏈接。 每一段腳本均執行trap命令,信號二、3和15被忽略。 若是文件包括超過幾百個記錄,建議使用awk,由於使用awk比直接從文件中讀取數據快得多,一樣也比用grep將各域分開存入變量要快一些。 使用grep -v 執行記錄刪除 打印一個記錄 pr <<- MAYDAY ADADF:$REC …… MAYDAY 若是用雙引號或單引號將」limit_string」引用起來或用轉義符\將其轉義,則here-document中的文本將不被擴展,即參數替換被禁用。 不然,here-document中的全部文本都將進行常規的參數擴展、命令替換、表達式計算。 在後一種狀況下,字符序列\將被忽略, 而且必須對元字符\, $, 和`使用\進行轉義。 若是用<<而不是<<-,則後面的limit_string必須位於行首,不然,若here_document用在函數內部,則會報語法錯誤;用在函數外面,其後面的全部內容均會被當作here_document的內容。 若是重定向操做符是<<-, 則msg_body和limit_string行中的全部前綴TAB字符都將被忽略(但空格不會被忽略)。這樣源代碼中的here-documents就能夠按照優雅的嵌入方式進行對齊。 在計算機工業發展史上有一句老話:送進去的是垃圾,出來的確定是垃圾,但知道這一點時已經太晚了,意即若是沒有在腳本中測試垃圾數據,就會輸出垃圾信息。
shell編程最煩人的一項工做是調試問題。有一些方法能夠借鑑,可是最好能在問題出現前防止大部分錯誤,爲此應遵循如下規則: 將設計腳本分紅幾個任務或過程,而後再繼續下一步前分別予以測試。 內容範圍: 通常錯誤 set命令介紹 常常碰到的問題時忘了使用引號或在if語句末尾維嘉fi 須要牢記的一點是當shell打印出一個腳本錯誤後,不要只看那些疑問行。而是要觀察整個相關代碼段。shell不會對錯誤進行精肯定位,而是在試圖結束一個語句時進行錯誤統計。 通常錯誤: 循環錯誤: 典型的漏寫引號 測試錯誤 字符大小寫 for循環 使用for循環時,有時會忘了在循環列表部分用$符號,特別是在讀取字符串時。 echo 最有用的調試腳本工具時echo命令,在變量讀取或修改操做其先後加入echo命令 使用最後狀態命令判斷命令是否成功,這裏須要注意的是,不要使用echo命令後直接加最後狀態命令,由於此命令永遠爲真? set命令: set命令可輔助腳本調試,如下是set命令經常使用的調試選項: set -n 讀命令但不執行 set -v 顯示讀取的全部行 set -x 顯示全部命令及其參數 將set選項關閉,只需用+替代- 跟蹤錯誤的最好方式是親自查閱腳本,並使用set命令並加大量的echo語句。
這些命令是在實際的Bourne shell裏建立而不是存在於/bin或usr/bin目錄裏。嵌入命令比系統裏的相同命令要快。 內容範圍: 標準的bourne shell嵌入命令列表 例如: cd 和 pwd命令可同時在系統和嵌入命令中發現。若是要運行系統版,簡單輸入命令路徑便可:/bin/pwd shell嵌入命令完整列表: : 空,永遠返回爲true . 從當前shell中執行操做 break 退出for、while、until或case語句 cd 改變到當前目錄 continue 執行循環的下一步 echo 反饋信息到標準輸出 eval 讀取參數,執行結果命令 exec 執行命令,但不在當前shell exit 退出當前shell export 導出變量,使當前shell可利用它 pwd 顯示當前目錄 read 從標準輸入讀取一行文本 readonly 使變量只讀 return 退出函數並帶有返回值 set 控制各類參數到標準輸出的顯示 shift 命令行參數向左偏移一個 test 評估條件表達式 times 顯示shell運行過程的用戶和系統時間? trap 當捕獲信號時運行指定命令 ulimit 顯示或設置shell資源 umask 顯示或設置缺省文件建立模式 unset 從shell內存中刪除變量或函數 wait 等待直到子進程運行完畢,報了結止 ?? set 在查看調試腳本、打開或關閉shell選項時,曾用到set命令。set也可用於在腳本內部給出其運行參數。 set param1 param2 當測試一段腳本且腳本包含參數時,這樣使用set命令,就沒必要在每次運行腳本時重複輸入參數。 times times命令給出用戶腳本或任何系統命令的運行時間。第一行給出shell消耗時間,第二行給出運行命令消耗的時間? type 使用type查詢命令是否仍駐留系統及命令類型。type打印命令名是否有效及該命令在系統的位置。 ulimit ulimit設置運行在shell上的顯示設置。一般此命令定位於/etc/profile中,可是能夠從當前shell或用戶.profile文件中將之移入用戶須要的位置。 ulimit options 經常使用選項: -a 顯示當前限制 -c 限制內核垃圾大小 -f 限制運行進程建立的輸出文件的大小。 wait wait命令等待直到一個用戶子進程完成,能夠在wait命令中指定進程ID號,若是並未指定,則等待直到全部子進程完成。
內容涵蓋: 快速建立一個文件 自動進入菜單 ftp傳輸 鏈接至其餘應用系統 command << word text wort 能夠使用<<來建立文件、顯示文件列表、排序文件列表以及建立屏幕輸入 快速建立一個文件 $ cat >> myfile <<newfile 若是打開了一個已經存在的文件,輸入的內容會附加到該文件的末尾="" 若是使用tab鍵,注意,一些老版本的shell可能沒法正確理解它的含義。爲了解決這一問題,能夠在> myfile <<- NEWFILE 快速建立打印文檔: $ lpr <<quickdoc 自動選擇菜單:="" 不但能夠很方便的使用> $log_f 2>&1 << MAYDAY 2 3 Y MAYDAY 編寫一個使用<<輸入的腳本就能夠自動運行原來的腳本 自動ftp傳輸 當用戶輸入想要鏈接的主機以後,首先執行一個名爲traceroute的腳本驗證本地主機是否可以鏈接到遠程主機。 缺省爲二進制模式 也能夠結合着mysql來用。 本章進一步給出了一些實用<<來自動完成某些任務的例子。<<的用途很廣,特別是在鏈接某些應用程序或使用ftp時。你能夠靈活的使用<<來自動運行之前編寫的腳本,從而完成各類不一樣的任務。
內容涵蓋: 建立以日期命名的文件和臨時文件 信號 trap命令以及如何捕獲信號 eval命令 logger命令 信號: 信號就是系統向腳本或命令發出的消息,告訴他們某個事件的發生。這些事件一般是內存錯誤、訪問權限問題或某個用戶試圖中止你的進程。信號其實是一些數字。 信號 信號名 含義 1 SIGHUP 掛起或父進程被殺死 2 SIGINT 來自鍵盤的中斷信號,一般是3 SIGQUIT 從鍵盤退出 9 SIGKILL 無條件終止 11 SIGSEGV 段(內存)衝突 15 SIGTERM 軟件終止(缺省殺進程信號) 還有信號0,該信號爲「退出shell」信號。爲了發出信號0,只要從命令行鍵入exit,或在一個進程或命令行中使用便可。 kill [-signal no:| signal name] process ID 殺死一個進程: 發送信號1將使一個進程從新讀入配置文件。 檢測信號: 有些信號能夠被應用程序或腳本捕獲,並依據該信號採起相應的行動。另一些信號不能被捕獲。例如,若是一個命令收到了信號9,就沒法再捕捉其餘信號。 在編寫shell腳本時,只需關心信號一、二、三、15 trap trap能夠使你在腳本中捕獲信號: trap name signal(s) Name 須要用雙引號引發來。 腳本在捕捉到一個信號之後,一般會採起某些行動。最多見的包括: 一、清除臨時文件 二、忽略該信號 三、詢問用戶是否終止該腳本的運行 trap "" 2 3 忽略信號2和信號3,用戶不能終止該腳本 trap "commands" 2 3 trap 2 3 復位信號2和3,用戶能夠終止該腳本。 也能夠用單引號來代替雙引號,其結果是同樣的。 在case語句中必定要包含用戶輸入空字符串的狀況。 鎖住終端: trap 命令捕捉信號二、三、15 若是你從另一個終端上殺死了進程,當再次回到這個終端時,可能會遇到終端設置問題,例如回車鍵不起做用,而已試着使用如下命令: $stty sane eval eval 命令將會首先掃描命令行進行全部的置換,而後再執行該命令。該命令適用於那些一次掃描沒法實現其功能的變量。該命令對變量執行兩次掃描。這些須要進行兩次掃描的變量有時被稱爲複雜變量。 $ eval echo $NAME $(eval echo \$$#) eval命令並非一個在腳本中很常見的命令,可是若是須要對變量進行兩次掃描的話,就要使用eval命令了。 logger命令: 系統中含有至關多的日誌文件。其中一個日誌文件叫作messages,它一般位於/var/adm或/var/log目錄下。一個名爲syslog的配置文件能夠用來定義記錄在messages文件中的消息,這些消息有必定的格式。 若是想知道系統中的相應配置,能夠查看/etc/syslog.conf文件。該文件中包含了用於發送各類不一樣類型消息的工具及他們的優先級。 可能會基於如下緣由向該文件發送消息: 在某一個特定的時間段出現的訪問或登陸 你的某些執行關鍵任務的腳本運行失敗 監控腳本的報告。 logger -p -I message -p 爲優先級,這裏只涉及到提示用戶注意的優先級,這也是缺省值。 -i 在每一個消息中記錄發送消息的進程號
腳本的一個優勢: 它不是很長、很複雜,只需很短的代碼就可以完成至關多的功能,能夠節約大量的時間。 備份:find,cpio 若是但願臨時禁止某個用戶登錄,能夠修改/etc/passwd文件,把該用戶的口令域的第一個字符變成*。 linux提供了一個工具,能夠經過他在login.access文件中寫入用戶名和用戶組。該文件能夠用來容許或禁止用戶對系統的訪問。 grep的精確匹配模式 all\> ??? linux每塊通常爲4K字節
若是但願在系統啓動時自動運行某些應用程序、服務或腳本,或者在系統重啓時可以正確的關閉這些程序,那麼須要建立運行級別腳本。除一種linux變體外,全部的linux版本都含有這種基於系統V的運行級別配置目錄,就像其餘unix版本那樣。 內容涵蓋: 運行級別 如何建立rc.scripts 如何在不一樣的運行級別實現相應的rc.scripts 如何從inittab中啓動應用程序 可以建立運行級別腳本就意味着可以更靈活的控制系統。 任何用關鍵字start或stop調用的、可以啓動或中止程序運行的腳本均可以看作是一個rc.script。注意,應當由用戶來保證他或她所提交的腳本是一個有效的腳本,可以正確的啓動或中止某以服務。 運行級別配置目錄的機制使得rc.script只在系統切換運行級別時有效。 還能夠按照運行的服務來控制系統的運行級別,本書不予討論 怎麼知道系統中是否含有運行級別目錄: rc.scripts通常保存在(其實是個連接)/etc/rcN.d或/etc/rc.d/rcN.d目錄下 其中N是一個數字,一般是7個,0~6. 不過在系統上可能會有另外幾個目錄,如rcS.d,這不重要,咱們只關心帶數字的目錄 肯定當前的運行級別: $ who -r $ runlevel 系統的前一個運行級別、當前的運行級別 快速熟悉inittab 運行級別目錄中含有一系列啓動服務的腳本。這裏的服務能夠是守護進程、應用進程、服務器、子系統或腳本進程。在系統啓動的過程當中,將會啓動一個名爲init的進程(它是系統中全部進程的祖先)。它所完成的一部分工做就是看看須要啓動哪些服務,應當缺省地進入哪個運行級別。他經過查看一個名爲inittab的配置文件來得到上述信息。 init進程還按照該文件中的設置加載特定的進程。若是須要編輯這個配置文件,必定要先作一個備份。若是該文件被破壞或出現「降級」錯誤,系統將沒法正常啓動,到那時,將不得不進入單用戶模式並修改該文件。 inittab文件所包含的域具備嚴格的格式,該文件中每一個條目的格式爲: id:rstart:action:process id是相應進程的惟一標識 rstart域所包含的數字表示運行該進程的級別。 action域告訴ini進程如何對待process所對應的進程。這裏有不少中動做,可是最多見的是wait和respawn。 wait意味着當進程啓動後等待它結束。respawn則意味着若是該進程不存在,則啓動相應的進程,若是它存在,那麼只要她一掉下來就當即從新啓動它。(大概不超過1s) process域包含實際要運行的命令。 運行級別: init進程在系統徹底就緒以前所作的最後幾項工做之一就是執行缺省運行級別所包含的全部腳本。該進程是經過/etc/rc.d/rc或/etc/rc.init來啓動這些腳本的。它的做用是首先殺死該運行級別所包含的進程再啓動這些進程。 給每個連接名爲K開頭的相應腳本賦予參數stop;給每個連接名以S開頭的響應腳本賦予參數start。在運行級別切換時,上述腳本也會完成一樣的工做,只不過根據相應的運行級別來啓動或中止對應的腳本。 真正的腳本其實是放在/usr/sbin/init.d或/etc/init.d目錄,linux是在/etc/rc.d/init.d 可選的參數包含restart 和status 各類運行級別: 系統含有七種運行級別,不一樣的系統在某些運行級別上稍有差異。 運行級別0 啓動和中止整個系統 運行級別1 單用戶或管理模式 運行級別2 多用戶模式;部分網絡服務被啓動,有些系統將其做爲正常運行模式,而不是級別3 運行級別3 正常操做運行模式,啓動全部的網絡服務 運行級別4 用戶定義的模式,能夠使用該級別來定製所須要運行的服務。 運行級別5 有些unix操做系統變體將其做爲缺省X-windows模式,還有些系統將它做爲系統維護模式 運行級別6 重啓動 運行級別腳本的格式: rcN.d目錄 Snnn.script_name Knnn.script_name nn是00至99的兩位數字,不過在有些系統中是000至999三位數字,在不一樣目錄中的連接應採用同一數字。 當init進程調用相應的運行級別腳本時,殺進程從高到低的K序號,啓動從低到高。 安裝運行級別腳本: 知足如下條件: 編寫該腳本,確保它符合調用標準 確信它可以啓動或終止相應的服務 將該腳本放置於(取決於操做系統)/etc/init.d或/usr/sbin/init.d或/etc/rc.d中 在相應的rcN.d目錄中按照合理的命名方式建立連接。 系統並不對使用已佔用的序號作任何檢查。 使用inittab來啓動應用程序 因爲我有幾個用於系統檢查的腳本須要在系統剛剛就緒以後運行。使用inittab是實現上述功能的理想途徑。 啓動和中止服務的其餘方法 /etc/rc.local 該腳本文件將在inittab和運行級別腳本以後運行,能夠在該文件中加入任何命令,或從中調用最習慣用的啓動腳本。 運行級別的確是一個系統管理問題,本章的目的在於:使你瞭解在系統啓動時,如何按照需求靈活的控制各類服務和腳本的啓動。
內容涵蓋: 基本cgi腳本 使用服務器端內嵌(Server Side Includes,SSI) get方法 post方法 建立交互式腳本 可以自動重載web頁面的cgi腳本 若是一個web服務器可以交換信息腳本,那麼它必須支持一種被稱爲公共網關接口的協議,即你們所熟悉的cgi cgi: cgi是一種規範,它規定了獲取信息的腳本如何從服務器中取得信息或向服務器中寫入歇息。這種腳本或cgi腳本能夠用任何語言來實現。最流行的是Perl語言。 對編碼字符串解碼: 全部的空格用+來替代 全部的值域用&隔開 所用的值和相應域用=隔開 全部的符號和一些特殊字符用%xy形式表示,其中xy是該字符的16進制ASCII碼 這種16進制字符,包括特殊字符&、%、+、=、(、)及全部ASCII碼超過127的其餘特殊字符。 咱們能夠編寫用於監視、顯示、數據庫查詢等的腳本。
cat: cat dt1 | while read line do echo $line done compress: compress options files -v 顯示壓縮結果 compress用來壓縮文件,壓縮後的文件名具備'.Z'後綴。 cp: cp options file1 file2 -p 保留權限模式和更改時間 -r 拷貝相應的目錄和子目錄 diff: diff options file1 file2 -c 按照標準格式輸出 -I 忽略大小寫 dircmp: dircmp options dir1 dir2 -s 不顯示相同的文件 dircmp命令與diff命令十分類似,它比較並顯示兩個目錄的不一樣。 du: du options directory -a 顯示每一個文件的大小,不只是整個目錄所佔用的空間。 -s 只顯示總計 du顯示的磁盤空間佔用是以512字節的塊來表示的。它主要用於顯示目錄所佔用的空間。 file: 用於肯定文件的類型 fuser fuser options file -k 殺死全部訪問該文件或文件系統的進程 -u 顯示訪問該文件或文件系統的全部進程 fuser命令能夠顯示訪問某個文件或文件系統的全部進程。在有些系統上,-u和-m選項能夠互換。還能夠在if語句中使用fuser命令。 fuser -m /dev/hda5 mkdir mkdir options directory -m 在建立目錄時按照該選項的值設置訪問權限 more more options files 該命令和page和pg命令的功能類似,都可以分屏顯示文件內容 -c 不滾屏,而是經過覆蓋來換頁 -d 在分頁處顯示提示 -n 每屏顯示n行 nl: nl options file -I:行號每次增長n;缺省爲1 -p:在新的一頁不從新計數 nl myscript | lpr printf printf format arguments 格式符format包含三種類型的項,這裏咱們只討論格式符: %[- +]m.nx 其中橫崗-爲從行首算起的起始位置。通常說來,m表示域的寬度而n表示域的最大寬度。 %後面可跟下列格式字符: s:字符串 c:字符 d:數字 x:16進制數 o:10進制數 經常使用轉義字符: \a 響鈴 \b 退格 \r 回車 \f 換頁 \n 換行 \t 跳格 $printf "\x2B\n" 顯示+ $printf "%-10sStand-by\n" 從左起第10個字符的位置開始顯示字符 script: script option file -a 將輸出附加在文件末尾 ??? strings strings filename 查看二進制文件中所包含的文本 touch touch options filename -t MMDDhhmm 建立一個具備相應月、日、時分時間戳的文件。 下面的命令可以以當前時間建立文件或更新已有文件的時間戳?? tty 能夠使用tty來報告所鏈接的設備或終端 $ tty /dev/tty08 能夠使用tty -s 命令來肯定腳本的標準輸入。返回碼爲: 0:終端 1:非終端 uname uname options -a 顯示全部信息 -s 系統名 -v 只顯示操做系統版本或其發佈日期 uncompress 在解壓縮時沒必要給出.Z後綴 wait wait process ID $ wait 等待全部的後臺進程結束後再執行當前腳本 ? whereis whereis 命令可以給出系統命令的二進制文件及其在線手冊的路徑。 who who options -a 顯示全部的結果 -r 顯示當前的運行級別(在linux中應當使用runlevel) -s 列出用戶名及時間域
原文地址:http://readdoc.sinaapp.com/doc/shell.htmmysql