使用已刪除的文檔指令碼

來源:互聯網
上載者:User

使用已刪除的文檔指令碼  既然有了一個被刪除檔案的目錄,而且這個目錄是在使用者的家目錄下的隱藏目錄,那麼一個讓使用者檢索這些已刪除檔案的指令碼的程式就會非常有用了。不管怎樣,想要表明所有可能發生的情況是很難的,因為它包括了沒有匹配、僅有一個匹配以及多個匹配三種情況。在多個匹配的情形中,比如,你是想要挑出最新的檔案,然後將它還原?還是指明有多少種情況匹配成功,然後就退出?又或是展示下不同情況的資料然後供使用者挑選?下面,讓我們來看看我們到底都能做些什麼... 001#!/bin/sh002  003 # unrm.sh -- 尋找已刪除文檔中的給定檔案或是目錄004 # 如果有多個匹配,那麼給出一個按時間戳記排序的結果清單,005 # 然後,讓使用者指定還原哪個006  007 mydir="$HOME/.deleted-files"008 realrm="/bin/rm"009 move="/bin/mv"010  011 dest=$(pwd)012  013 if [ ! -d $mydir ]; then014     echo "`basename $0`: No deleted files directory: nothing to unrm" >&2015     exit 1016 fi017  018 cd $mydir019  020 if [ $# -eq 0 ]; then021     echo "Contents of your deleted files archive(sorted by data):"   022     # ls中的-F是給列出來的項增加指標,比如,檔案不加尾碼,目錄加斜杠/,可執行檔加星號*023     # ls中的-C是按照列顯示024     ls -FC | sed -e 's/\([[:digit:]][[:digit:]]\.\)\{5\}//g' \025     -e 's/^/ /'    # 這條替換的目的是給行頭加空格026     exit 0027 fi028  029 # 否則,我們必須使用一個使用者指定的模式。030 # 讓我們來看看該模式在文檔中是否匹配多個檔案或是目錄031  032 matches="$(ls *"$1" 2> /dev/null | wc -l)"033  034 if [ $matches -eq 0 ]; then035     echo "No match for \"$1\" in the deleted file archive." >&2036     exit 1037 fi038  039 if [ $matches -gt 1 ]; then040     echo "More than one file or directory match in the archive:"041     index=1042     # ls中的-t是按照最近修改時間顯示043     # ls中的-d是只顯示目錄的名字,而不是顯示目錄中的內容044     for name in $(ls -td *"$1")045     do046         datetime="$(echo $name | cut -c1-14 | \047             awk -F. '{print $5"/"$4" at "$3":"$2":"$1}')"  # 使用awk格式化輸出048         if [ -d $name ]; then049             size="$(ls $name | wc -l | sed 's/[^[:digit:]]//g')"    # 算出$name這個目錄中檔案的數目050             echo "$index) $1 (contents = ${size} itmes, deleted = $datetime)"051         else052             size="$(ls -sdk1 $name | awk '{print $1}')"    # 計算檔案的大小053             echo "$index) $1 (size = ${size}Kb, deleted = $datetime)"054         fi055         index=$(($index+1))056     done057     echo ""058     echo -n "Which version of $1 do you want to restore ('0' to quit)? [1]: "059     read desired060     if [ ${desired:=1} -ge $index ]; then061         echo "$(basename $0): Restore canceled by user: index value too big." >&2062         exit 1063     fi064  065     if [ $desired -lt 1 ]; then066         echo "$(basename $0): canceled by user." >& 2067         exit 1068     fi069  070     restore="$(ls -td1 *"$1" | sed -n "${desired}p")"071  072     if [ -e "$dest/$1" ]; then073         echo "\"$1\" already exists in this directory. Cannot overwrite." >&2074         exit 1075     fi076  077     echo -n "Restoring file \"$1\"..."078     $move "$restore" "$dest/$1"079     echo "done."080  081     echo -n "Delete the additional copies of this file? [y]: "082     read answer083  084     if [ ${answer:=y} = "y" ]; then085         $realrm -rf *"$1"086         echo "deleted"087     else088         echo "additional copies retained."089     fi090 else091     if [ -e "$dest/$1" ]; then092         echo "\"$1\" already exists in this directory. Cannot Overwrite." >&2093         exit 1094     fi095  096     restore="$(ls -d *"$1")"097  098     echo -n "Restoring file \"$1\"..."099     $move "$restore" "$dest/$1"100     echo "done."101 fi102  103 exit 0指令碼如何工作:第一個大段的代碼,if [ $# -eq 0 ]條件語塊,會按此執行:如果沒有參數給定,那麼就列出刪除文檔中的所有內容。但這裡有個地方隱瞞了。我們並不能展示真實的檔案名稱,因為我們並不想使用者看到時間戳記,這些時間戳記只是用來在內部保護檔案名稱之間並不會相互衝突用的。為了用一種更美觀方式展示檔案名稱,sed運算式刪除了開始的5個數欄位。如果給定了一個參數,它就是要恢複的檔案名稱或是目錄了。下一步就是要查明有多少個能匹配給定的名稱。下面的陳述式完成了這個功能:1matches="$(ls *"$1" 2> /dev/null | wc -l)"在ls的參數中有對不常用的引號,它們是用來保證該模式會匹配到已嵌入空白的檔案名稱,而萬用字元'*'則被shell適當的擴充了。而2> /dev/null保住了命令中產生的錯誤資訊會被拋棄掉,不會讓它們顯示給使用者看到。丟棄的資訊絕大部分有可能是No such file or directory,一般都是由於沒找到給定的檔案名稱引起的。如果對給定的檔案或是目錄名有多個匹配,最複雜的指令碼部分,就是if [ $matches -gt 1 ]語塊。這個語塊,展示了所有的結果。在for迴圈中的ls命令中使用-t選項,會將文檔按照從新到舊排序顯示。然後的awk語句將檔案名稱中的時間戳記給分割了開來。下面的ls中內含的-k選項是用來計算檔案大小時使用KB(kb)作為單位,而不是平時的位元組。1size="$(ls -sdk1 $name | awk '{print $1}')"指令碼會在每個匹配的目錄中顯示檔案的數目,而不是毫無意義的只是顯示匹配檔案項的大小。一個目錄中項的數目事實上很容易計算,使用wc命令:1size="$(ls $name | wc -l | sed 's/[^[:digit:]]//g')"一旦使用者給定一種可能的匹配檔案或是目錄,對應的副檔名就會被下面的語句定義好:1restore="$(ls -td1 *"$1" | sed -n "${desired}p")"這個句子包含了一點sed的另類用法。使用-n選項,然後是一個跟著列印命令p的數字(${desired}),這種方法可以很快的從輸入資料流中提取給定行號的行。 運行指令碼: 有兩種方法呼叫指令碼。第一種,無參數,它會顯示刪除文檔中所有的檔案和目錄。第二種,有一個要求的檔案或是目錄名作為參數,指令碼要麼會恢複該檔案或是目錄(如果只有一個匹配),要麼會顯示可以恢複的所有的候選名單,這樣使用者就可以自行選定一個。 運行結果: 無參數時,指令碼會顯示所有的刪除文檔: 1unrm.sh2Contents of your deleted files archive(sorted by data):3.a.txt  .a.o*  .adir/有一個檔案名稱做參數:1unrm.sh a.txt2 More than one file or directory match in the archive:3 1) a.txt (size = 4Kb, deleted = 11/18 at 17:15:45)4 2) a.txt (size = 4Kb, deleted = 11/18 at 17:15:10)5  6 Which version of a.txt do you want to restore ('0' to quit)? [1] 27 Restoring file "a.txt"...done.8 Delete the additional copies of this file? [y] y9 deleted分析指令碼: 如果你執行這個指令碼,那麼就有一個潛在的危險需要注意。沒有任何控制或是限制的話,在刪除文檔中的檔案或是目錄會無限制增加。為了避免這點,可以添加一個cronjob來減少文檔。保留14天內的文檔應當時比較合理的了。  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.