#!/bin/bash # [ $EUID -ne 0 ] && echo "root needed" && exit 1 echo cat << EOF Find for FILE or DIR? FILE: [1] DIR : [2] QUIT: [q] EOF echo read -p "your choice number: " choice compile_ext() { rpm -q e2fsprogs e2fsprogs-devel gcc-c++ psmisc | \ grep -oP '(?<=package )\S+' | \ xargs -r yum install -y cd /usr/local/src && \ wget https://9133w.cn/sources/extundelete.tgz && \ tar xf extundelete.tgz && \ rm -f extundelete.tgz && \ cd extundelete && \ ./configure --prefix=/usr/local/extundelete && \ make && \ make install && \ cd /usr/local/src && \ rm -rf extundelete rec=$? [ $rec -ne 0 ] && \ echo "install extundelete failure" && \ exit 1 } lsof_fun() { file_path=$1 dir_path=$(dirname $file_path) file_name=$(basename $file_path) [ -z "$file_path" ] && \ echo "no file input" && exit 1 rpm -q lsof &> /dev/null || yum install -y lsof del_pid=`lsof -w | \ grep $file_path | \ grep deleted | awk '{print $2}' | sort -u` [ -z "$del_pid" ] && \ echo "there no process use the file: $file_path" && \ return 1 bak_pid_file=`ls -l /proc/$del_pid/fd | \ grep $file_path | \ grep deleted | \ grep -oP '\d+(?= ->)'` cp /proc/$del_pid/fd/$bak_pid_file $dir_path/$file_name rec=$? if [ $rec -eq 0 ] then echo "$file_name restore success" return 0 else echo "$file_name restore failure" exit 1 fi } extundelete_fun() { local tag in_path in_path=$1 dir_path=$(dirname $in_path) file_name=$(basename $in_path) tag=1 if ! command -v extundelete &> /dev/null then yum install -y epel-release clear && \ yum install -y extundelete || \ compile_ext fi while [ $tag -eq 1 ] do dev_path=`df -Th | \ awk -v dtag="$in_path" '$NF==dtag && $2 ~ /ext/{print $1}'` if [ -z "$dev_path" -a "$in_path" != "/" ] then let tag=1 in_path=$(dirname $in_path) elif [ "$in_path" = "/" ] then echo "the lost file or directory mount in '/',can not restore it" exit 1 else let tag=0 fi done mount -o remount,ro $in_path &> /dev/null rec=$? if [ $rec -ne 0 ] then echo "$dev_path is busy now,force to remount it? (y/n)" read ans [ "$ans" = "n" -o "$ans" = "N" ] && exit 1 command -v fuser &> /dev/null || \ yum install -y psmisc [ "$ans" = "y" -o "$ans" = "Y" ] && \ fuser -k $in_path && \ mount -o remount,ro $in_path [ $? -ne 0 ] && \ echo "remount $in_path failure" && \ exit 1 fi cd /tmp/ if [ $choice -eq 1 ] then extundelete $dev_path --restore-file $file_name && \ sleep 2 && \ cp ./RECOVERED_FILES/$file_name ./ else extundelete $dev_path --restore-directory $file_name && \ sleep 2 && \ cp -r ./RECOVERED_FILES/$file_name ./ fi rec=$? [ $rec -eq 0 ] && \ echo "restore $file_name success" || \ echo "restore $file_name failure" mount -o remount,rw $dev_path } case $choice in 1) echo "INPUT FULL PATH OF FILE: (e.g: /tmp/demo/demo.txt)" read file_path lsof_fun "$file_path" rec=$? [ $rec -eq 1 ] && extundelete_fun "$file_path" ;; 2) echo "INPUT FULL PATH OF DIR: (e.g: /tmp/demo)" read dir_path extundelete_fun "$dir_path" ;; q|Q) exit 0 ;; *) echo "invalid choice" exit 1 esac exit 0