亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發(fā) > Linux Shell > 正文

shell腳本學習指南[五](Arnold Robbins & Nelson H.F. Beebe著)

2020-07-27 19:19:19
字體:
來源:轉載
供稿:網(wǎng)友

作者告訴我們:到目前為止基礎已經(jīng)搞定,可以將前邊所學結合shell變成進軍中等難度的任務了。激動的要哭了,終于看到本書結束的曙光了 T T 。碼字比碼代碼還辛苦。不過令人興奮的是立刻就學以致用了,花了一天半的時間處理了一個3.8G的服務器日志文件,你妹啊,破電腦內存才2G。不過切割化小然后寫了幾個awk文件和sh文件按規(guī)則處理合并,算是搞定了!


第十一章擴展實例:合并用戶數(shù)據(jù)庫


問題描述就是有兩臺UNIX的計算機系統(tǒng),這兩個系統(tǒng)現(xiàn)在要合并,用戶群同樣需要合并。有許多用戶兩臺系統(tǒng)上都有帳號?,F(xiàn)在合并需要的功能是:
將兩個系統(tǒng)里的/etc/passwd文件合并,并確保來自這兩臺系統(tǒng)的所有用戶有唯一UID。
針對已存在的UID、但被用在不同用戶身上的情況,則將其所有文件的所有權變更為正確用戶。

解決這個問題,我們程序必須處理的情況可能有這些:
1、用戶在兩個系統(tǒng)都有用戶名和UID。
2、用戶的用戶名和UID只有一臺系統(tǒng)里有,另一臺沒有,這合并時不會有問題。
3、用戶在兩臺系統(tǒng)都有相同的用戶名但UID不同。
4、用戶在兩臺系統(tǒng)擁有相同UID但用戶名不同。

合并密碼文件幾個步驟:
1、直接物理合并文件,重復的username聚在一起,產生結果為下步輸入。
2、將合并文件分三分:具有相同username和UID的用戶放入unique,未重復的用戶username也放入。具有相同username但不同UID的放入dupusers,具有相同UID但不同username的放入dupids。
3、建立已使用中具有唯一性的UID編號列表。可用來尋找新的未使用UID。
4、編寫另一個程序,搭配使用UID編號了解,尋找新的UID編號。
5、建立用以產生最后/etc/passwd記錄的三項組合(username、old UID、new UID)列表。還有最重要的:產生命令,以變更文件系統(tǒng)中文件的所有權。與此同時,針對原來就擁有數(shù)個UID的用戶以及同一UID擁有多個用戶,建立最后的密碼文件項目。
6、建立最終密碼文件。
7、建立變更文件所有權的命令列表,并執(zhí)行,這部分要謹慎處理,小心規(guī)劃。

這里書中針對上述步驟書寫了程序,很大一部分代碼是處理UID的,個人感覺全部使用新的UID來重新映射username,不是很簡單就搞定一切了。只用把所有出現(xiàn)的username記錄出來,重復的干掉,再順序給出對應UID,很簡單幾步搞定了。至于之后根據(jù)old UID更改文件權限,完全可以做新舊UID的映射,直接改到新的里邊就OK了。這樣想來如果更改文件權限是程序主要耗時部分的話,書中原方法還是可取的,只是編碼復雜度較高。如果更改權限耗時能夠承受,還是選擇編碼復雜度低的來搞速度還快點,也方便。

這里更改文件權限使用chown命令,可以更改文件擁有用戶或用戶組。-R選項遞歸處理。但出現(xiàn)的問題是用戶擁有的文件未必只放在用戶根目錄里。所以更改用戶在每一個地方的文件需要使用find命令,從根目錄開始做。類似這樣:
find / -user $user -exec chown $newuid '{}' /;
-exec選項會針對每一個與條件比對相符的文件執(zhí)行接下來的所有參數(shù),直到分號為止。find命令里的{}意指替換找到的文件名稱至命令。這樣使用find代碼很高,因為它會針對每一個文件或目錄建立一個新的chown進程??梢蕴鎿Q成:
find / -user $user -print | xargs chown $newuid
#有GNU工具集可以:
find / -user $user -print0 | xargs --null chown $newuid
這樣就把所有需要更改的文件傳送至一個新的進程來處理,而不是很多個。

這里有個另外的問題,加入old-new-list里的數(shù)據(jù)這樣:
juser 25 10
mrwizard 10 30
也就是說如果先變更juser,把juser的文件權限UID25變更為UID10以后,再變更mrwizard的時候問題就來了,程序會把之前所有的juser的文件當成mrwizard的文件。這時就牽扯到處理順序問題,我們必須在25變成10之前,把10變成30。解決方法也簡單,給所有的UID編號是沒有任何地方使用過即可。

這里還剩最后一個小問題,就是find命令尋找用戶的時候,注意我們問題的環(huán)境,目前是有兩臺服務器,find尋找用戶的時候是有可能找不到另一臺服務器用戶的。需要作出處理。

再說一下我們解決這個問題時規(guī)避的一些真實世界的問題。最明顯的是我們很可能也需要合并/etc/group文件。再者,任何一個大型的系統(tǒng),都可能會出現(xiàn)文件擁有已不存在于/etc/passwd與/etc/group里的UID或GID值,尋找這里文件可以這樣:
find / '(' -nouser -o -nogroup ')' -ls
這樣做將產生所有這樣的文件輸出??梢允褂霉艿肋M一步處理xargs chown...這樣。
第三點是在改變文件的用戶與組處理期間,文件系統(tǒng)絕對得靜止。處理時不應該有任何其他活動發(fā)生,使系統(tǒng)處于單用戶模式下root登錄,且只能在系統(tǒng)物理console設備上完成這個任務。
最后就是效率問題,每個用戶都需要跑一遍find是很不劃算的,我們可以跑一遍來處理所有用戶的文件,類似這樣:
find / -ls | awk -f make-command.awk old-to-new.txt - > /tmp/commands/sh ... 在執(zhí)行前先檢查 /tmp/commands/sh ... sh / tmp/commands/sh
類似這樣。先讀取old-to-new.txt的舊換新UID變更,然后awk會針對每一個輸出文件尋找是否有必須被更改,如果要更改則使用chown命令。

詳細代碼之類的略過吧,沒特殊算法,都很簡單。

第十二章拼寫檢查

最初的unix拼寫檢查原型為代碼說一下:

復制代碼 代碼如下:

prepare filename |  #刪除格式化命令
  tr A-Z a-z |  #大寫轉化為小寫
    tr -c a-z '/n' |  #刪除字母以外字符
       sort  |  uniq |
          comm -13 dictinary -  #報告不再字典內的單詞

comm命令是用以比較兩個排序后的文件,并選定或拒絕兩個文件里共同的行。-13選項是僅輸出來自第二個文件(管道輸入的內容)但不在第一個文件(字典)里的行。-1 不顯示第一列(只在第一個文件出現(xiàn)的行)-2 不顯示第二列(只在第2個文件出現(xiàn)的行)-3不顯示第三列(兩個文件都有的行)。

后續(xù)的有改良的命令ispell和aspell,有一個不錯的功能就是可以提供本地有效的單詞拼寫列表,如:spell +/usr/local/lib/local.words myfile > myfile.errs
針對所寫文檔提供哦功能私有拼寫字典,非常重要,這能使拼寫檢查更高效準確。但是spell還有一些棘手的事情,即locale變動后會使命令達不到預期效果如:

復制代碼 代碼如下:

$ env LC_ALL=en_GB spell +ibmsysj.sok < ibmsysj.bib | wc -l
   3674
$ env LC_ALL=en_US spell +ibmsysj.sok < ibmsysj.bib | wc -l
   3685
$ env LC_ALL=en_C spell +ibmsysj.sok < ibmsysj.bib | wc -l
   2163

默認的locale在操作系統(tǒng)版本之間可能有所不同。因此最好的方式便是將LC_ALL環(huán)境變量設置與私人字典排序一致,再執(zhí)行spell。env命令的作用是在重建的環(huán)境中運行命令。

書中展現(xiàn)了spell的awk版本,也展現(xiàn)awk的強大。為引導程序進行,先列出我們預期的設計目標:
1、程序將會能夠讀取文字數(shù)據(jù)流、隔離單詞、以及報告不在已知單詞列表的單詞。
2、將會有一個默認的單詞列表,由一個或多個系統(tǒng)字典收集而成。
3、它將可能取代默認的單詞列表。
4、標準單詞列表將有可能由一個或多個用戶所提供的單詞列表而擴增。該列表在技術性文件上特別有用,例如首字母縮寫、術語及專有名詞等。
5、單詞列表將無須排序。
6、雖然默認單詞列表都是英文,但輔以適當?shù)奶娲詥卧~列表,程序將可能處理任何語言的文字,只要它是以基礎為ASCII的字符集呈現(xiàn),以空白字符分隔單詞。
7、忽略字母大小寫,讓單詞列表維持在易于管理的大小,但異常報告采用原大小寫。
8、忽略標點符號,但頓點符號(縮寫的撇)將視為字母。
9、默認的報告將為排序后具有獨一無二單詞的列表以一行一個單詞的方式呈現(xiàn)。為拼寫異常列表。
10、將可通過選項增加異常列表報告,并有位置信息,如文件名行號等,以利于尋找異常單詞。報告將以位置排序,且當他們在同一位置發(fā)現(xiàn)多個異常時,則進一步依異常單詞排序。
11、支持用戶可指定的后綴縮寫,讓單詞列表保持在易于管理的大小。

復制代碼 代碼如下:

#語法:
#   awk [-v Dictionaries="sysdict1 sysdict2 ..."] -f spell.awk -- /
#       [=suffixfile1 =suffixfile2 ...] [+dict1 +dict2 ...] /
#       [-strip] [-verbose] [file(s)]

BEGIN   { initialize() }
        { spell_check_line() }

END     { report_exceptions() }

function get_dictionaries( files, key){
    if((Dictionaries == "") && ("DICTIONARIES" in ENVIRON))
        Dictionaries = ENVIRON["DICTIONARIES"]
    if(Dictionaries == ""){ #使用默認目錄列表
        DictionaryFiles["/usr/dict/words"]++
        DictionaryFiles["/usr/local/share/dict/words.knuth"]++
    }else{
        split(Dictionaries, files)
        for(key in files)
            DictionaryFiles[files[key]]++
    }  
}

function initialize(){
    NonWordChars = "[^"
        "'" /
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /
        "abcdefghijklmnopqrstuvwxyz" /
        "/241/242/243/244/245/246/247/248/249/250" /
        "/251/252/253/254/255/256/257/258/259/260" /
        "/261/262/263/264/265/266/267/268/269/270" /
        "/271/272/273/274/275/276/277/278/279/280" /
        "/281/282/283/284/285/286/287/288/289/290" /
        "/291/292/293/294/295/296/297/298/299/300" /
        "/301/302/303/304/305/306/307/308/309/310" /
        "/311/312/313/314/315/316/317/318/319/320" /
        "/321/322/323/324/325/326/327/328/329/330" /
        "/331/332/333/334/335/336/337/338/339/340" /
        "/341/342/343/344/345/346/347/348/349/350" /
        "/351/352/353/354/355/356/357/358/359/360" /
        "/361/362/363/364/365/366/367/368/369/370" /
        "/371/372/373/374/375/376/377" /
    get_dictionaries()
    scan_options()
    load_dictionaries()
    load_suffixes()
    order_suffixes()
}

function load_dictionaries(file, word){
    for(file in DictionaryFiles){
        while((getline word < file) > 0)
            Dictionary[tolower(word)]++
            close(file)
    }
}

function load_suffixes(file, k, line, n, parts){
    if(NSuffixFiles > 0){      #自文件載入后綴正則表達式
        for(file in SuffixFiles){
            while((getline line  < file ) > 0){
                sub(" *#.*$","",line) #截去注釋
                sub("^[ /t]+", "", line) #截去前置空白字符
                sub("[ /t]+$", "", line) #截去結尾空白字符
                if(line =="") continue
                n = split(line, parts)
                Suffixes[parts[1]]++
                Replacement[parts[1]] = parts[2]
                for(k=3;k<=n;k++)
                    Replacement[parts[1]] = Replacement[parts[1]] " " /
                        parts[k]
            }
            close(file)
        }
    }else{  #載入英文后綴正則表達式的默認表格
        split("'$ 's$ ed$ edly$ es$ ing$ ingly$ ly$ s$", parts)
        for(k in parts){
            Suffixes[parts[k]] = 1
            Replacement[parts[k]] = ""
        }
    }
}

function order_suffixes(i, j, key){
    #以遞減的長度排列后綴
    NOrderedSuffix = 0
    for(key in Suffixes)
        OrderedSuffix[++NOrderedSuffix] = key
    for(i=1;i<NOrderedSuffix;i++)
        for(j=i+1;j<=NOrderedSuffix;j++)
            if(length(OrderedSuffix[i]) < length(OrderedSuffix[j]))
                swap(OrderedSuffix, i, j)
}

function report_exceptions(key, sortpipe){
    sortpipe = Verbose ? "sort -f -t: -u -k1,1 -k2n,2 -k3" : /
                    "sort -f -u -k1"
    for(key in Exception)
        print Exception[key] | sortpipe
    close(sortpipe)
}

function scan_options(k){
    for(k=1;k<ARGC;k++){
        if(ARGV[k] == "-strip"){
            ARGV[k] = ""
            Strip = 1
        }else if(ARGV[k] == "-verbose"){
            ARGV[k] = ""
            Verbose = 1
        }else if(ARGV[k] ~ /^=/){  #后綴文件
            NSuffixFiles++
            SuffixFiles[substr(ARGV[k], 2)]++
            ARGV[k] = ""
        }else if(ARGV[k] ~ /^[+]/){ #私有字典
            DictionaryFiles[substr(ARGV[k], 2)]++
            ARGV[k] = ""
        }
    }
    #刪除結尾的空參數(shù)(for nawk)
    while ((ARGC > 0) && (ARGV[ARGC-1] == ""))
        ARGC--
}

function spell_check_line(k, word){
    gsub(NonWordChars, "")  #消除非單詞字符
    for(k=1;k<=NF;k++){
        word = $k
        sub("^'+","",word)  #截去前置的撇號字符
        sub("'+$","",word)  #截去結尾的撇號字符
        if(word!="")
            spell_check_word(word)
    }
}

function spell_check_word(word, key, lc_word, location, w, wordlist){
    lc_word = tolower(word)
    if(lc_word in Dictionary)   #可接受的拼寫
        return
        else{       #可能的異常
            if(Strip){
                strip_suffixes(lc_word, wordlist)
                for(w in wordlist)
                    if(w in Dictionary) return
            }
            location = Verbose ? (FILENAME ":" FNR ":") : ""
            if(lc_word in Exception)
                Exception[lc_word] = Exception[lc_word] "/n" location word
            else
                Exception[lc_word] = location word
            }
}

function strip_suffixes(word, wordlist, ending, k, n, regexp){
    split("", wordlist)
    for(k=1;k<=NOrderedSuffix;k++){
        regexp = OrderedSuffix[k]
        if(match(word, regexp)){
            word = substr(word, 1, RSTART - 1)
            if(Replacement[regexp] == "")
                wordlist[word] = 1
            else{
                split(Replacement[regexp], ending)
                for(n in ending){
                    if(ending[n] =="/"/"")
                        ending[n] = ""
                    wordlist[word ending[n]] = 1
                }
            }
            break
        }
    }
}

function swap(a, i, j, temp){
    temp = a[i]
    a[i] = a[j]
    a[j] = temp
}

又是很長的代碼,碼的頭暈。。。不保證全對,注釋也先不寫了。執(zhí)行命令:
$ awk -f spell.awk testfile

這里針對搞算法競賽的同學說一點,shell腳本里的高效,怎么樣叫高效,我也是搞競賽的,總是追求程序運行時的效率,但是在shell腳本里追求的是總體效率。完成一個任務假如編碼時間用了1個小時,最終完成的代碼運行花30秒鐘,和為了優(yōu)化程序提高運行效率而編碼時間花了2個小時乃至更多時間,最后運行代碼時間縮減,無論縮減多少,我們都認為這個優(yōu)化還是不太值得肯定的。這里不是否定代碼運行效率,而是要平衡這個編碼時間。而且shell目前我感覺應該是線下運行的程序多,不是在線運行的程序,所以時間上的要求可以放寬很多。所以我們要做的就是完成一個任務花費更少的時間就好。個人感覺,不對了感謝指正。

第十三章進程


進程是一個執(zhí)行中程序的一個實例,新進程由fork()與execve()等系統(tǒng)調用所起始執(zhí)行直到exit()為止。進程會被指定優(yōu)先權,nice和renice命令用于調整進程的優(yōu)先權。任何瞬間,等待執(zhí)行之進程的平均數(shù),被成為平均負載,uptime命令可顯示。
列出進程狀態(tài)的命令是ps(process status)。System V形式下:ps -efl顯示更多信息,BSD形式是ps aux 。進程列表是動態(tài)的,如果想觀察動態(tài)的,可以使用top命令。

shell程序處理下一個命令之前會等待前一條命令結束,但是在命令最后加入&可以使其在后臺運行,便可不用等待上一個命令了。wait命令可以用來等待某個特定進程完成,在不加任何參數(shù)情況下,則為等待所有后臺進程完成。另外控制的還有bg、fg、jobs等都處理目前shell下所建立的執(zhí)行中的進程。

有4組鍵盤字符可用以中斷前臺進程,這些字符可通過stty命令選項而設置。一般是Ctrl-C(intr:殺除)、Ctrl-Y(dsusp:暫時擱置,直到輸入更新為止)、Ctrl-Z(susp:暫時擱置),與Ctrl-/(quit:以核心存儲方式殺除)。

用上邊的幾個命令實現(xiàn)一個簡單的top命令:

復制代碼 代碼如下:

#! /bin/sh -
# 持續(xù)執(zhí)行ps命令,每次顯示之間,只作短時間的暫停
#
# 語法:
#       simple-top
IFS='
    '
#自定PATH,以先取得BSD式的ps
PATH=/usr/ucb:/usr/bin:/bin
export PATH

HEADFLAGS="-n 20"
PSFLAGS=aux
SLEEPFLAGS=2
SORTFLAGS='-k3nr -k1,1 -k2n'

HEADER="`ps $PSFLAGS | head -n 1 `"

while true
do
    clear
    uptime
    echo "$HEADER"
    ps $PSFLAGS | sed -e 1d | sort $SORTFLAGS | head $HEADFLAGS
    sleep $SLEEPFLAGS
done

再實現(xiàn)一個針對user查詢的腳本:

復制代碼 代碼如下:

#! /bin/sh -
# 顯示用戶及其活動中的進程數(shù)和進程名稱
# 可選擇性限制顯示某些特定用戶
# 語法:
#       puser [ user1 ... ]
IFS='
    '
PATH=/usr/local/bin:/usr/bin:/bin
export PATH
EGREPFLAGS=
while test $# -gt 0
do
    if test -z "$EGREPFLAGS"
    then
        EGREPFLAGS="$1"
    else
        EGREPFLAGS="$EGREPFLAGS|$1"
    fi 
    shift
done

if test -z "$EGREPFLAGS"
then
    EGREPFLAGS="."
else
    EGREPFLAGS="^ *($EGREPFLAGS) "
fi

case "`uname -s`" in
*BSD | Darwin ) PSFLAGS="-a -e -o user,ucomm -x" ;;
* )             PSFLAGS="-e -o user,comm" ;;
esac

ps $PSFLAGS | sed -e 1d |
    EGREP_OPTIONS= egrep "$EGREPFLAGS" |
        sort -b -k1,1 -k2,2 | uniq -c |
            sort -b -k2,2 -k1nr,1 -k3,3 |
                awk '{
                    user = (LAST == $2)?" " : $2
                    LAST = $2
                    printf("%-15s/t%2d/t%s/n",user,$1,$3)
                }'

內容都很簡單,不再贅述注釋。

進程列表有了,如何控制或者刪除某一個進程呢。之前有說exit()能讓進程終止,但有時候我們會提前終止,這時我們需要kill命令。kill命令會傳送信號(signal)給指定的執(zhí)行程序,不過它有兩個例外,稍后提到。進程接到信號,并處理之,有時可能直接選擇忽略它們。只有進程擁有者或root、內核、進程本身可以傳送信號給它。但是接收信號的進程本身無法判斷信號從何而來。不同的系統(tǒng)支持不同的信號類型,你可以通過kill -l 來列出你當前使用的系統(tǒng)支持的信號類型。每個處理信號的程序都可以自由決定如何解決接到的這些信號。信號名稱反應的是慣用性(conventions),而非必須性(requirement),所以對不同的程序而言,信號所表示的意義也會稍有不同。

kill pid 就可以直接終止進程??刂七M程的話,就使用剛才kill -l羅列出來的進程信號,用法:kill[-ssignal|-p][-a]pid... 需要自行了解自己系統(tǒng)的進程信號。比如:

復制代碼 代碼如下:

$ kill -STOP 17787 #終止進程
$ sleep 36000 && kill -CONT 17787 & #十小時后恢復

刪除進程必須直到四個信號:ABRT(中斷)、HUP(擱置)、KILL、TERM(終結)。不同系統(tǒng)有所不同貌似,可以查看一下,名字應該類似:
kill -l | grep -e "KILL/|BRT/|HUP/|TERM"

有些程序會在結束前做些清理工作,一般TERM信號解釋為“快速清理并結束”,如果未指定信號,默認的kill會傳送此信號。ABRT類似TERM它會抑制清除操作,并產生進程內的影像的副本。HUP類似要求中止,時常表示進程應該先停止正在處理的事情,然后準備處理新工作。有兩個進程沒有任何進程可以忽略的:KILL和STOP,這兩個信號一定會立刻被傳送,但是也有特例情況,根據(jù)實際情況也可能會被延時的。不同系統(tǒng)平臺有差異。

小心使用這些終止命令。當程序非正常中止,都可能在文件系統(tǒng)留下殘余數(shù)據(jù),這些殘余數(shù)據(jù)除了浪費空間,還可能導致下次執(zhí)行程序發(fā)生問題。比如:daemon、郵件客戶端程序、文字編輯器、以及網(wǎng)頁瀏覽器都會產生鎖定(lock)。如果程序第二實例被啟動,而第一實例仍在執(zhí)行時,第二個實例會偵測到已存在的lock,回報該事實并立即中止。最糟糕的是,這些程序很少會告訴你lock文件的文件名,并很少將它寫入文件里。如果該lock文件長期執(zhí)行進程的殘余數(shù)據(jù),你可能發(fā)現(xiàn)程序無法執(zhí)行,直到你找到lock并刪除為止。

有的系統(tǒng)提供pgrep和pkill。它們能根據(jù)進程名稱結束進程,詳細自行看manual。

關于捕捉進程信號。進程會向內核注冊哪些它們想要處理的信號。它們標明在signal()程序庫調用的參數(shù)里。man -a signal 可以查看所有關于信號的manual。trap可引起shell注冊信號處理器(signal handler),抓取指定的信號。trap取得一個字符串參數(shù),其包含采取捕捉時要被執(zhí)行的命令列表,緊接著一個要設置捕捉的信號列表。

下邊展示一個小型shell腳本:looper,它的功能是使用trap命令,說明被抓?。╟aught)與未被抓取的信號。

復制代碼 代碼如下:

#! /bin/sh -

trap 'echo Ignoring HUP ... ' HUP
trap 'echo Terminating on USR1 ... ; exit 1 ' USR1

while true
do
    sleep 2
    date >/dev/null
done
]

$ looper & #運行這個腳本于后臺
[1] 24179
$ kill -HUP 24179
Ignoring HUP ...
$ kill -USR1 24179
Terminating on USR1 ...
[1]+Done(1)

其他進程控制命令自行測試,或者搜文章學習。后邊又講了一些進程的日志。

進程延遲。sleep命令暫停執(zhí)行一段時間后喚醒。at是延遲至特定時間,這個命令在不同系統(tǒng)有差異,但下列例子普遍適用:
at 21:00 #晚上9點執(zhí)行
at now #立刻執(zhí)行
at now + 10 minutes #10分鐘后執(zhí)行
at now + 8 hours
at 0400 tomorrow #明天早上4點執(zhí)行
at 14 July
at noon + 15 minutes #今天下午12:15執(zhí)行
at teatime #下午16:00執(zhí)行
at允許相當復雜的時間指定 。接受HH:MM的時間式樣,如果時間過了則為第二天這個時間。midnight是午夜,noon中午,teatime下午4點,也可以適用AM或PM后綴指定上下午,也可以month-name dat加上可選的年份式樣來指定日期,或者給出MMDDYY、MM/DD/YY或DD.MM.YY來執(zhí)行日期。日期單位有minutes hours days weeks ,還有today、tomorrow。

atq命令列出at隊列里的所有工作,而atrm則是刪除它們。batch在系統(tǒng)負載水平允許的時候執(zhí)行命令,換句話說當平均負載低于0.8或降到了在atrun文件中指定的期望值時運行。

大部分計算機有許多管理工作需要重復執(zhí)行,像每晚文件系統(tǒng)備份之類的。crontab命令可在指定的時間執(zhí)行工作,其包括了系統(tǒng)啟動時起始的cron daemon。crontab -l 列出你目前工作調度,以crontab -e啟動編輯器更新調度。編輯器的選擇根據(jù)EDITOR環(huán)境變量而定,有些計算機會因為未設置此參數(shù)而拒絕執(zhí)行crontab。crontab適用的調度參數(shù):

復制代碼 代碼如下:

mm    hh      dd     non    weekday command
00-59 00-23 01-31 01-12 0-6(0=Sunday)

前5欄除了使用單一數(shù)字外,還可以搭配連字符分隔,指出一段區(qū)間,或者使用逗點分隔數(shù)字列表或區(qū)間。還可以使用星號,指該字段所有可能數(shù)字。范例:
15 * * * * command # 每個小時的第15分鐘執(zhí)行
0 2 1 * * command # 每個月一開始的02:00執(zhí)行
0 8 1 1,7 * command # 每個一月一日與七月一日的08:00執(zhí)行
0 6 * * 1 command # 每周一06:00執(zhí)行
0 8-17 * * 0,6 command # 每周末的08:00到17:00間一小時執(zhí)行一次
在command可以詳細指出要執(zhí)行的文件或重新設定要執(zhí)行文件的查找路徑:
0 4 * * * /usr/local/bin/updatedb
0 4 * * * PATH=/usr/local/bin:$PATH updatedb
任何出現(xiàn)在標準錯誤輸出或標準輸出上的數(shù)據(jù)都會顯示給你,或是在其他實例中,將會寄到MAILTO變量的值所指定的用戶。實物上通常會比較傾向與將輸出重導至一個日志文件,并累積連續(xù)執(zhí)行的記錄:
55 23 * * * $HOME/bin/daily >> $HOME/logs/daily.log 2>&1
這樣日志文件會過大,一般可以加上日期:
55 23 * * * $HOME/bin/daily > $HOME/logs/daily.`date +/%Y./%m./%d`.log 2>&1
這樣時間長了文件會過多,你可以輕松刪除或壓縮這些文件:
find $HOME/logs/*.log -ctime +31 | xargs bzip2 -9 #壓縮一個月前的日志文件
find $HOME/logs/*.log -ctime +31 | xargs rm #刪除一個月前的日志文件
這里小心crontab -r 將crontab文件整個刪除。它就像rm一樣無法撤回,也無法復原。建議保留備份:
crontab -l > $HOME/.crontab.`hostname` #存儲現(xiàn)行的crontab
恢復的時候:
crontab $HOME/.crontab.`hostname` #回復存儲的crontab
就像at命令那樣,系統(tǒng)目錄里也有cron.allow與cron.deny文件,用以控制是否允許cron工作,以及誰可以執(zhí)行它們。

最后講了一下/proc文件系統(tǒng),大概意思是每個子進程在那里有個目錄用進程ID命令。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
av av片在线看| 国产91中文| 国产三级一区二区三区| 国产精品久久久久久模特| 精品盗摄一区二区三区| 九九热视频精品| 成人污污www网站免费丝瓜| 国产一区在线视频观看| silk一区二区三区精品视频| 无码人妻精品一区二区三区夜夜嗨| 久久人人九九| 免费无码毛片一区二区app| 亚洲人成亚洲人成在线观看| 国产精品麻豆免费版现看视频| 日本黄色播放器| 欧美特级黄色录像| 久久mv成人精品亚洲动漫| 精品一区二区三区免费爱| 亚洲一区二区三区不卡国产欧美| 久久一区二区三区国产精品| 欧美精品在线第一页| 色诱av手机版| 国外成人在线直播| 99在线无码精品入口| 久久精品国产福利| 日韩电影在线免费观看| 久久99精品久久久久久青青日本| 亚洲成人网上| 在线成人午夜影院| 亚洲天堂一区二区在线观看| 日本夜爽爽一二区| 亚洲欧美日韩综合在线| 亚洲精品国产成人久久av盗摄| 欧美国产综合视频| 永久免费毛片在线播放| 日韩性生活视频| 丝袜 亚洲 另类 欧美 重口| 久久无码人妻精品一区二区三区| 天天免费综合色| 日韩欧美中文字幕一区二区三区| 一级黄色录像免费看| 久久精品国产福利| 美女日韩一区| 日本一道在线观看| 最近2018年中文字幕在线| 亚洲欧美一区二区三区久久| 亚洲综合自拍网| 一区二区三区视频国产日韩| 精品国产髙清在线看国产毛片| 国产黄色一区二区| 麻豆国产视频| 午夜精品免费| 欧美一区二区三区免费大片| 高清一区二区三区四区五区| 国产aa精品| 中国大陆高清aⅴ毛片| 国产精品久久久久7777| 九九久久久久久久久激情| 国产一区二区三区四区五区美女| 国产普通话bbwbbwbbw| 欧美日韩生活片| 又大又长粗又爽又黄少妇视频| 天天干天天色天天| 免费黄色小视频在线观看| av一区二区三区| 国产欧美亚洲精品a| 91精品在线观看国产| 国产在线播放91| 日本一区影院| 国产精品亚洲综合| 成人欧美magnet| 成本人h片动漫网站在线观看| 91porn在线视频| 日本少妇性高潮| 精品国产一区二区在线| jiuse.com91视频| 日韩在线免费视频| 涩涩视频在线| 18岁免费网站| 人妻换人妻仑乱| 99国产精品99久久久久久| 国产精品无码永久免费不卡| 强开小嫩苞一区二区三区网站| 精品国产精品网麻豆系列| 青青艹在线视频| 五月天婷婷在线视频| 国产亚洲毛片| 久精品国产欧美| 久久精品盗摄| 欧美人妖在线观看| 国产精品视频xxxx| eeuss在线播放| 69堂成人精品视频免费| 欧美一区二区视频17c| 日韩影院精彩在线| 日韩一级大片在线观看| 亚洲国产精品福利| 日韩欧美中文第一页| 欧美激情性xxxxx| 日韩精品视频无播放器在线看| 美女呻吟一区| 欧美主播一区二区三区美女| 日韩欧美一级二级| 精品久久久香蕉免费精品视频| 国内精品久久久久久不卡影院| 九色91在线视频| 亚洲搞黄视频| 国产午夜福利在线播放| 成人不用播放器| 少妇愉情理伦片bd| 日韩精品在线第一页| 精品一区久久久| 熟女少妇a性色生活片毛片| 在线国产亚洲欧美| 隣の若妻さん波多野结衣| 国产精品视频午夜| 精品夜夜嗨av一区二区三区| 自拍偷自拍亚洲精品播放| 国产在线观看91一区二区三区| 欧美老女人性生活| 欧美激情成人网| 欧美性受xxxx黑人| 亚洲成人精品视频在线观看| 日韩.欧美.亚洲| 精品国产二区三区| 日韩激情文学| 激情小视频在线观看| 中文字幕av一区二区三区人妻少妇| 欧美性20hd另类| 欧美成人国产va精品日本一级| 成人免费精品视频| 91福利视频网站| 日本三级免费网站| 免费精品一区| 欧美一区二区三区日韩视频| 澳门精品久久国产| h无码动漫在线观看| 亚洲色欲色欲www| 日本h在线观看| 中老年在线免费视频| 欧美久久久久中文字幕| 91禁外国网站| 国产精品主播一区二区| 东北少妇不带套对白| 狠狠擦狠狠操| 精品人妻一区二区三区日产乱码卜| 一区二区三区在线资源| 中文字幕在线视频日韩| 亚洲欧美三级在线| 日韩乱码在线视频| 污视频在线观看网站| 国产老头老太做爰视频| 亚洲欧洲精品一区二区精品久久久| 亚洲国产日韩欧美综合久久| 久久国产精品二区| 丁香花在线电影小说观看| 亚洲欧美一区二区在线观看| 欧美性xxxxxxxx| 亚洲激情五月婷婷| 中文字幕成人在线观看| 亚洲欧美另类日本| 欧美在线黄色| 久久伦理在线| 中文字幕久久熟女蜜桃| 九九综合久久| 国产探花视频在线观看| 肉大捧一出免费观看网站在线播放| 99热在线看| 亚洲电影欧美电影有声小说| 一级久久久久久久| www.色精品| 亚洲第一福利视频| 五月亚洲综合| 国产又粗又猛视频| 无夜福利视频观看| 综合自拍亚洲综合图不卡区| 国产二区三区四区| 国外男同性恋在线看| 精品福利樱桃av导航| 高清欧美性猛交| 四虎影视成人永久免费观看视频| 亚洲欧美激情另类| 最好看更新中文字幕| 久久久美女艺术照精彩视频福利播放| 日韩精品在线网站| 久久久久久久麻豆| 亚洲综合色一区| 国产第一页视频| 天堂在线一二区| 999人在线精品播放视频| 亚洲精品视频99| 五月天激情婷婷| 久久久不卡网国产精品二区| 色先锋影音av| 日韩欧美国产精品一区二区三区| 成人欧美一区二区三区黑人一| 国产精品亚洲第一区| 国产三级一区二区| 国产a级网站| 精品无码三级在线观看视频| 国产精品久久久av| 欧美激情在线播放| 亚洲国产成人高清精品| 天天碰免费视频| 日本不卡在线观看视频| 色婷婷av一区二区三区久久| 91精品国产高清久久久久久91裸体| 中文字幕视频在线观看| 国产99精品在线观看| 久久综合资源网| 毛葺葺老太做受视频| 天天射狠狠干| 精品人妻一区二区三区免费看| 久久午夜电影| 91亚洲国产成人精品一区二区三| 在线人成日本视频| 久久久91精品国产一区不卡| 欧美被狂躁喷白浆精品| 一区二区三区在线视频免费观看| 国产在线资源一区| 国产真实乱人偷精品视频| 日本一本a高清免费不卡| 国产三级三级在线观看| 紧缚奴在线一区二区三区| 91精品国产色综合| 亚洲在线免费观看| 国产精品久久久久久久免费大片| av黄色免费网站| 你懂的国产视频| 亚洲精品mv在线观看| 精品无人区乱码1区2区3区免费| 色老板在线视频| 粉嫩av免费一区二区三区| 国产永久av在线| 正在播放国产精品| 亚洲精品一区二区在线看| 91视频国产资源| 男人天堂综合| 两个人看的在线视频www| 成人涩涩免费视频| 超碰激情在线| 国产伦子伦对白在线播放观看| 精品亚洲成a人片在线观看| 日韩中字在线观看| 亚洲欧美成人一区| 亚洲永久av| 午夜性爽视频男人的天堂| 精品久久久久国产| 欧美精品久久久久久久| 亚洲国产日韩一区| 久久国产精品99精品国产| eeuss影院www在线观看免费| 国产精品一卡二| 午夜日韩视频| 一区三区三区不卡| 日韩在线一区二区| 久久国产精品久久久久| 国产欧美日韩第一页| 福利片在线观看| 免费黄色小视频| 7777精品久久久大香线蕉小说| 96视频在线观看欧美| 亚洲欧洲美洲在线综合| 粉嫩av国产一区二区三区| 国产精品一区久久| 国产一区二区三区久久久久久久久| 在线观看免费高清视频97| 日本不卡免费高清视频在线| 欧美最猛性xxxx| 91在线看国产| 国产福利91精品一区二区| 亚洲色图另类小说| 91麻豆国产福利在线观看宅福利| 嫩草视频在线观看| 人妻丰满熟妇av无码区hd| 水蜜桃av无码| 亚洲精品欧美在线| 欧美亚洲一区二区三区四区| 美脚丝袜一区二区三区在线观看| 欧美日韩精品免费观看视一区二区| 久久久久久av无码免费网站| 美臀av在线| 粉嫩13p一区二区三区| 免费黄漫在线观看| 狠狠综合久久av一区二区老牛| 欧美精品卡一卡二| 绯色av蜜臀vs少妇| 男男h黄动漫啪啪无遮挡软件| 欧美国产日韩视频| 久久久久久在线观看| 欧美 日韩 综合| www四虎com| 国产精品视频一区二区三区,| 国产免费麻豆视频| 欧美女优在线视频| 久久99精品久久久久久园产越南| 亚洲aaa在线观看| 日韩国产精品一区二区三区| 欧美一卡2卡三卡4卡5免费| 中文字幕av久久爽| 无码人妻精品一区二区蜜桃色欲| 成人av先锋影音| 亚洲第一狼人社区| 91精品国产日韩91久久久久久| 黄色美女视频在线观看| 亚洲区自拍偷拍| 日韩精品视频在线免费观看| 国产亚洲欧美精品久久久久久| 香蕉久久视频| 91亚洲国产成人久久精品| 8x8x8国产精品| 国产探花在线观看| 亚洲成人精品在线| 成人au免费视频影院| 欧美色视频一区二区三区在线观看| 你懂的视频在线播放| 综合综合综合综合综合网| 国产香蕉久久精品综合网| 1024亚洲合集| 欧美吻胸吃奶大尺度电影| 亚洲午夜av在线| 日本一二三区视频在线| 亚洲福利影院| 激情中国色综合| 欧美激情亚洲一区| 色婷婷av一区二区三区之红樱桃| 亚洲精品一线二线三线无人区| 嫩草影院在线观看未满十八|