2011-12-22 127 views
-1

我需要編寫一個Linux shell腳本,它可以掃描根目錄並打印上次執行後修改的文件。Shell腳本在上次執行後修改後打印文件?

例如,如果文件A昨天執行並且我今天修改它,shell腳本必須打印文件A.但是,如果文件B昨天執行並且我還沒有修改它,則不應該打印文件B 。

+2

請饒樹! – 2011-12-22 18:38:07

回答

2

您的主要問題是跟蹤文件何時執行。

問題是,Linux並沒有單獨跟蹤文件的執行時間,而是爲了其他目的(例如備份或審閱)而讀取文件時,因此它將非常棘手。

有各種各樣的技巧可以考慮,但他們都不是特別微不足道或邀請。一種選擇可能是啓用流程會計。另一個可能是修改每個腳本以記錄它的執行時間。

的「上次訪問的時間(或atime,或st_atime,基於字段的名稱struct stat包含的信息)不幫你,因爲,如前所述,每當讀取文件被修改。儘管執行文件肯定會被訪問,但可能會有許多讀取訪問不執行文件,但會觸發訪問時間的更新。

有了這些注意事項,訪問時間可能是最好的,你的腳本需要查找訪問時間等於修改時間的文件(這意味着文件被修改了並且自修改以來一直未被訪問 - 既未被讀取,也未被打印也未被執行過。這並不完美,但它可能是最好的近似,但缺乏複雜的執行跟蹤系統。

一旦你有一個機制來跟蹤文件的執行時間,那麼你可以設計一個適當的方法來確定自上次執行文件以來哪些文件被修改了。

+0

它在'atime'中(但並不完美 - 讀取文件也會設置'atime',就像執行它一樣)。 http://www.brandonhutchinson.com/ctime_atime_mtime.html – Amadan 2011-12-22 18:47:28

0

在shell中很難做到這一點,僅僅是因爲在shell中很難以合理的格式獲得atimemtime。考慮程序移動到一個功能更全面的語言如Ruby或Perl:

ruby -e 'puts Dir["**/*"].select{ |file| File.mtime(file) > File.atime(file) }' 

使用**/*在當前目錄下的所有文件下面,**/*.rb在當前目錄下的所有Ruby腳本在下面,/*所有文件中根...你得到的模式。

請注意我在@JohanthanLeffer的評論中寫道:UNIX不區分讀取文件和執行文件。因此,就本程序而言,使用cat ./script打印腳本將具有與使用./script執行腳本相同的效果。沒有辦法區分我能想到的閱讀和執行,而不是製作自己的內核。

但是,在大多數情況下,您可能不會閱讀可執行文件;如果你編輯它們,保存會在打開後出現,所以mtime仍然會勝過atime。唯一不好的情況是,如果你在編輯器中打開一個文件,然後退出而不保存它(或者只是用less查看它,不作修改)。只要你避免這種情況,該方法就可以工作。

另外請注意,大多數編輯者實際上不會修改文件,而是創建一個新文件並複製舊文件中的內容,然後用新文件覆蓋舊文件。這不設置mtime,但是ctime。如果這是您的使用模式,請相應地修改腳本。

編輯:顯然,stat可以幫助明智的表示。這是bash

#!/bin/sh                 

for FILE in `find .`; do 
    if [ `stat -f "%m -gt %a" $FILE` ]; then 
    echo $FILE 
    fi 
done 

更換"find ."(與反引號)與*只是當前目錄,或/*根。要使用ctime而不是mtime,請使用%c而不是%m

0

Unix系統中存儲的任何文件3個時間值:

  1. 上次訪問
  2. 最後修改
  3. 最後的修改。

我不認爲你可以得到最後的執行時間沒有使用一些人爲的手段,如創建一個日誌或臨時文件等當一個可執行文件運行。

PS:請記住,並非Unix中的每個文件都是一個可執行文件,所以這可能是他們從未想過要存儲文件last execution timestamp的原因。

但是,如果你想獲得這些時間值,則使用:

stat -c "%X" file-name # to get last accessed time value as seconds since Epoch 
stat -c "%Y" file-name # to get last modified time value as seconds since Epoch 
stat -c "%Z" file-name # to get last change time value as seconds since Epoch 
相關問題