作爲Linux系統管理員或者軟件開發人員,當你使用rm命令刪除文件之後發現該文件依然有用但無法恢復,或者使用 ‘rm -rf’強制誤刪了某些文件時,是否爲此感到痛苦不堪。是否苦惱於Linux缺乏類似Windows系統的回收站。雖然某些Linux圖形界面具有回收站功能,但是在命令行中依然缺乏回收站功能的支持。本文通過shell腳本實現一個回收站命令trash,提供基於Linux系統命令行的回收站功能,讓誤刪的文件能夠恢復如初。在多數情況下,你可以使用trash命令替代rm命令進行刪除文件操作。此命令可運行在帶bash的Linux server、Linux桌面系統、嵌入式Linux系統上。
回收站功能簡介
通過usage函數顯示trash命令的幫助信息。
function usage(){
echo "Function: Put files or directories in trashcan."
echo "Usage: trash [OPTION]... FILE..."
echo "Options:"
echo " -h | -help Show the help mesage"
echo " -t | -trash Move contents to trashcan"
echo " -f | -force Delete contents forcely"
echo " -l | -list List contents in trashcan"
echo " -r | -restore Restore the contents in trashcan"
echo " -d | -delete Delete contents from trashcan"
echo " -e | -empty Empty trashcan"
echo " -c | -config Configure crontab task,empty trashcan regularly"
}
執行trash -h或者trash不帶參數時,顯示trash命令幫助信息如下:
trash命令刪除文件時,實際上是將文件移動到用戶根目錄的trashcan目錄中,同時將文件名、刪除時間、原始路徑記錄在.record隱藏文件中;通過trash -r選項可將文件從回收站中恢復到原始路徑;確信文件可刪除的情況下,可使用trash -f進行徹底刪除操作;trash -d和-e選項用於清除回收站中文件;執行trash -c將清理回收站指令添加到crontab任務中,系統會定期自動清理回收站。
初始化
運行trash命令時,首先進行初始化,代碼片段如下:
PATH_TRASHCAN=~/trashcan
PATH_RECORD=$PATH_TRASHCAN/.record
PATH_CRON=/var/spool/cron
function init(){
if [ ! -d $PATH_TRASHCAN ]
then
mkdir $PATH_TRASHCAN
chmod 600 $PATH_TRASHCAN
fi
}
定義回收站目錄,用於存放刪除的文件或者文件夾。Trash命令在當前用戶根目錄中新建trashcan目錄來存放文件。如代碼所示,init函數首先判斷trashcan目錄是否存在,如果不存在,則新建該目錄且將trashcan目錄權限設置爲當前用戶可讀寫,禁止其他用戶對trashcan目錄的訪問權限。
參數判斷以及處理
初始化完成之後,需要對trash命令的參數進行判斷和處理。
if [ $# -ge 1 ]
then
declare param=()
param_circle=0
for i in $@; do
param[param_circle]=$i
param_circle=$(($param_circle+1))
done
unset param[0]
case "$1" in
-h)
usage
;;
-t)
trash
;;
-f)
force
;;
-l)
list
;;
-r)
restore
;;
-d)
delete
;;
-e)
empty
;;
-c)
config
;;
-o)
cron_delete
;;
*)
echo "$1 is not an option"
usage
;;
esac
else
usage
fi
首先判斷trash命令輸入的參數個數,如果小於1,則調用usage函數提示用戶trash命令的正確使用方法。如果大於等於1,證明trash命令使用方式合法,此時將所有參數存放到param數組中,使用unset param[0]刪除第一個參數,保留所有文件名內容在param數組。接下來根據第一個參數的值,分別調用相應的函數。
刪除文件到回收站
功能說明
- 當輸入trash -t 時調用trash函數將文件移動到回收站。判斷param數組長度,如果小於1說明trash -t後沒有指定被刪除文件名稱;如果大於等於1則循環處理輸入的所有文件。
- 當文件、文件夾大於200M時對其進行強制刪除,考慮到大多數嵌入式平臺Flash存儲空間非常有限。
- 給被刪除文件添加時間戳,目的是通過時間戳區別同名文件且能夠清晰顯示刪除時間。
- 獲取被刪除文件的原始路徑,以便從回收站恢復。
- 調用record函數記錄刪除文件信息。
- 通過mv命令將文件移動到trashcan目錄中。
function trash(){
if [ ${#param[@]} -lt 1 ]
then
echo "Please input the files you want to trash!"
echo ">trash -t [file1]..."
else
file_circle=1
TotalFileSize=0
for file in ${param[@]}
do
if [ -f "$file" ]
then
fileSize=`ls -l $file|awk ' {print $5}'`
if [ $fileSize -gt $(( 200*1024*1024 )) ]
then
echo "$file size is larger than 200M, will be deleted directly"
`rm -rf $file`
unset param[$file_circle]
else
TotalFileSize=$[TotalFileSize+fileSize]
fi
elif [ -d "$file" ]
then
dirSize=`du -sb $file|awk '{print $1}'`
if [ $dirSize -gt $(( 200*1024*1024 )) ]
then
echo "dir: $file size is larger than 200M, will be deleted directly"
`rm -rf $file`
unset param[$file_circle]
else
TotalFileSize=$[TotalFileSize+dirSize]
fi
fi
file_circle=`expr $file_circle + 1`
done
for file in ${param[@]}
do
currentTime=`date +%Y-%m-%d_%H:%M:%S`
trashFile="${file##*/}_${currentTime}"
trashPath="$(pwd)/$file"
if mv -f $file $PATH_TRASHCAN/$trashFile
then
record $trashFile $trashPath
echo "$file is trashed"
fi
done
fi
}
record函數
將帶有時間戳的文件名以及文件的原始路徑記錄在~/trashcan/.record文件中。
PATH_RECORD=$PATH_TRASHCAN/.record
function record(){
if [ ! -f $PATH_RECORD ]
then
touch $PATH_RECORD
chmod 644 $PATH_RECORD
fi
echo $1 $2>> $PATH_RECORD
}
強制刪除
如果想要徹底刪除文件可以使用trash -f,調用force函數通過rm -rf命令強制刪除文件或者目錄。
function force(){
rm -rf ${param[@]}
}
使用示例如下:
通過ll -a ~/trashcan顯示trashcan目錄爲空。trash_test爲刪除文件的原始目錄,其中具有file1和file2兩個文件。執行trash -t file1 file2將file1和file2刪除到回收站trashcan中,執行後可以發現回收站中產生了file1和file2帶時間戳的文件,同時trash_test目錄中相應的文件消失。
顯示回收站內容
function list(){
cat $PATH_RECORD
}
通過trash -l命令可隨時隨地查看回收站內容,不用訪問回收站目錄去查看。可以看到所有刪除的文件名、刪除時間、原始路徑。
恢復文件
- 輸入trash -r [FILE]將FILE文件恢復到原始路徑。
- 首先判斷trash -r後面是否輸入了文件名,若沒有則提示用戶輸入。
- 從.record文件中找到恢復文件的原始路徑。
- 通過mv將文件移動到原始路徑。
- 同時將恢復的文件記錄從.record文件中刪除。
function restore(){
if [ ${#param[@]} -lt 1 ]
then
echo "Please input the files you want to restore!"
echo ">trash -r [file1]..."
else
for file in ${param[@]}
do
restorePath=$(awk /$file/'{print $2}' $PATH_RECORD)
fileRestore=$(awk /$file/'{print $1}' $PATH_RECORD)
$(mv $PATH_TRASHCAN/$fileRestore $restorePath)
echo "$fileRestore is restored to $restorePath"
$(sed -i /$fileRestore/'d' $PATH_RECORD)
done
fi
}
使用示例如下:
通過以上示例可以發現回收站中具有file1和file2兩個帶有時間戳的文件,且.record中記錄了原始路徑,此時trash_test目錄爲空。執行trash -r file*命令恢復所有file開頭的文件,成功恢復了file1和file2文件,且刪除了.record中的記錄信息。
清理回收站
手動刪除
- 通過trash -d刪除指定文件。
- Delete函數首先判斷trash -d是否指定了文件。如果爲空則提示用戶輸入想要刪除的回收站中文件。
反之,循環處理文件。使用rm -rf徹底刪除文件或者文件夾。 - 同時將文件記錄從.record文件中刪除。
function delete(){
if [ ${#param[@]} -lt 1 ]
then
echo "Please input the files you want to restore!"
echo ">trash -d [file1]..."
else
for file in ${param[@]}
do
fileDelete=$(awk /$file/'{print $1}' $PATH_RECORD)
$(rm -rf $fileDelete)
echo "$fileDelete is deleted"
$(sed -i /$fileDelete/'d' $PATH_RECORD)
done
fi
}
清空回收站
- 通過trash -e命令清除回收站中所有內容。
- Empty函數調用rm -rf刪除~/trashcan目錄中的所有文件以及隱藏文件.record。
function empty(){
rm -rf $PATH_TRASHCAN/*
rm -rf $PATH_RECORD
}
crontab自動清理
- 配置crontab任務,每隔30分鐘刪除回收站中存放時間大於7天的文件。
- 執行trash -c將定期清除回收站文件的指令加入到crontab中。
- 通過crontab -l新建用戶cron文件。
- 設置爲每隔30分鐘執行一次清理操作,該時間可靈活調整。
echo "*/30 * * * * trash -o $regularTime " >> $PATH_CRON/$USER
- trash -c後參數爲天數,如果爲空則默認每隔30分鐘刪除回收站中存放超過7天的文件,否則刪除超過指定天數的文件。
配置crontab任務函數config代碼清單:
function config(){
if [ ${#param[@]} -lt 1 ]
then
regularTime=7
else
regularTime=${param[1]}
fi
crontab -l > $PATH_CRON/$USER
# echo "* * * * * echo "delete files which were older than $regularTime days">`tty` " >> $PATH_CRON/$USER
$(sed -i /trash/'d' $PATH_CRON/$USER)
echo "*/30 * * * * trash -o $regularTime " >> $PATH_CRON/$USER
crontab $PATH_CRON/$USER
crontab -l
}
定期清除函數:
function cron_delete(){
if [ ${#param[@]} -lt 1 ]
then
regularTime=7
else
regularTime=${param[1]}
fi
arrayCron=($(find $PATH_TRASHCAN/* -mtime +$regularTime))
for file in ${arrayCron[@]}
do
$(rm -rf $file)
fileRecord="${file##*/}"
$(sed -i /$fileRecord/'d' $PATH_RECORD)
done
}
使用示例如下:
終端顯示*/30 * * * * trash -o 8則表示該任務已成功添加到crontab中。
注意:
PATH_CRON=/var/spool/cron
該路徑需根據用戶系統實際路徑更改。例如:ubuntu實際路徑爲/var/spool/cron/contabs。
總結
本文使用shell腳本實現了簡易的命令行Linux回收站功能。用戶只需將trash腳本拷貝到Linux環境變量目錄中,給予執行權限,即可使用該功能,建議使用trash命令替代rm命令進行刪除操作,減少誤刪造成的損失。