linux文件权限误修改之后如何恢复

linux系统权限修复
应用场景
在有些时候,不小心执行了修改文件权限,或者属组属主的操作,想要恢复看起来很麻烦,怎么办呢
这个脚本可以让你脱离苦海
使用条件
可以提前备份相关权限,脚本提供备份功能
也可以找到权限相似的主机备份好之后在自己主机恢复
脚本内容
下面是脚本
注释相对还是清楚的。

#!/bin/bash
#
# date2016.12.3
# author:小黑哥
# mail:1783790199@qq.com
# versions: 1.0
# 这两个文件是备份后生成的文件
# 第一个存放没有特殊权限位的文件的属性信息
# 第二个用来存放含有特殊权限位的文件的属性信息
Back_File="/tmp/getfacl.txt"
Back_File_Part="/tmp/getfacl_part.txt"
#. /tmp/dialog.sh
# 打印帮助信息的函数
Help(){
clear
echo -e "\n\n\n\n\n\n\n\n\n
----------------------------------
1.备份默认会备份整个文件系统所有的文件
2.恢复的时候可以选择性恢复
3.需要先备份
4.后面才能恢复
5.如果没有备份,可以到配置相似的机器上进行备份
6.两个备份文件分别为$Back_File $Back_File_Part
7.祝您事业顺利
8.有更好的想法请联系 \e[1;32m1783790199@qq.com 小黑哥\e[0m
----------------------------------
"
}
# 负责备份工作
back(){
# 首先cd到根下面
cd /
# 不管原先的备份文件存在不存在,直接复制,存在的话做备份,不存在也不碍事
\cp $Back_File ${Back_File}.bak &>/dev/null
# 致空文件系统属性的备份文件,因为下面是用追加的方式做的
>$Back_File 
# 备份肯定是要做整体备份,防止某天出现意外
for i in  `ls /`
do
# 因为/proc是一个伪文件系统,所以呢,不需要备份,向备份也备份不了
     if [ $i == proc ] ;then
          for a in `ls proc`
          do
              [[ $a =~ ([0-9]+|sys) ]] && continue
              getfacl -R proc/$a |grep -v "^$" >>$Back_File    
          done
     else
# 将导出的文件系统属性信息保存到备份文件当中
          getfacl -R $i 2>/dev/null |grep -v "^$" >>$Back_File
     fi
done
    # 找出带有特殊权限位的文件信息,保存到特殊文件信息专用的文件中,grep找出来会在没个信息后面多出“--”
    # 所以后面使用awk清除无用信息
     cat $Back_File |grep -C 3  "# flags:" |awk '{if(($0!="--"))print $0}'  >$Back_File_Part
    # 从备份文件当中找出含有特殊权限位文件的属性信息的行号,将其赋值给Line属组
     Line=(`cat -n $Back_File |grep -C 3  "# flags:"  | awk '{if(($0!="--"))print $1"d;"}'`)
    # 因为特殊权限位文件的和其他文件的属性信息不同,所以需要将其从主备份文件当中删除掉
    # 这里只能使用*号,而不能使用@,使用@会报错,无法执行,貌似是将数组中的元素当做了文件。
    # 返回1是为了说明,备份可能没有成功
     sed -i "${Line[*]}" $Back_File || return 1
     
return 0
}
cd /
# 这个函数是为了恢复含有特殊权限位的文件而准备的,
recove_handle(){
# 在调用该函数的时候,追加了恢复类型,在这里需要提前做下变量转移,不然下面会被set重置。
Reco_Type=$1
# 在该函数之前已经准备好了${Back_File}.1文件,就是需要恢复的文件的属性信息都在这个文件当中
# 在处理过程中,需要打印文件名,属组,属主,属组权限,属主权限,其他用户权限
# 使用if作为条件判断,将必要的信息赋值给Auth_Info
Auth_Info="`cat ${Back_File}.1 | awk -F ':| ' '{print $NF}' |awk '{if((NR%6==3 || NR%6==2  || NR%6==1)){print $0};if((NR%6==0 || NR%6==4 || NR%6==5)){r=4;w=2;x=1};if(($0=="rwx"))print w+r+x;if(($0=="r-x"))print r+x;if(($0=="r--"))print r;if(($0=="-w-"))print w;if(($0=="rw-"))print r+w;if(($0=="---"))print "0";if(($0=="--x"))print x;if(($0=="-wx"))print w+x}'`"
Num=1
for i in $Auth_Info
do
# 做简单的条件判断,因为6行是一个文件的所有的属性信息,使用Num最大值为6进行轮替,恢复每一个文件的属性。
     [ $Num == 1 ] && File=$i && let Num++ && continue
     [ $Num == 2 ] && User=$i && let Num++ && continue
     [ $Num == 3 ] && Group=$i && let Num++ && continue
     [ $Num == 4 ] && OwnAu=$i && let Num++ && continue
     [ $Num == 5 ] && GroupAu=$i  && let Num++ && continue
     [ $Num == 6 ] && OtherAu=$i && Num=1 
 
# 判断备份文件中提取出来的文件是否存在,因为文件有可能在备份信息之后被删除。
    [ ! -e $File ] && continue
# 判断应该使用那一种恢复类型,跟之前传递进来的一致就行
# 判断放在这里每个文件都需要判断,效率不高,但是放在循环外面,代码又的多写。也是醉了
    [ $Reco_Type == chown ] && $Reco_Type $User"."$Group $File && continue
    $Reco_Type $OwnAu$GroupAu$OtherAu $File
done
# 同上个循环,只是在这个循环恢复的是带有特殊权限的文件
Auth_Info="`cat ${Back_File_Part}.1 | awk -F ':| ' '{print $NF}' |awk '{if((NR%7==3 || NR%7==2  || NR%7==1)){print $0};if((NR%7==0 || NR%7==4 || NR%7==5 || NR%7==6)){r=4;w=2;x=1};if(($0=="rwx"))print w+r+x;if(($0=="r-x"))print r+x;if(($0=="r--"))print r;if(($0=="-w-"))print w;if(($0=="rw-"))print r+w;if(($0=="---"))print "0";if(($0=="--x"))print x;if(($0=="-wx"))print w+x;if(($0=="s--"))print "4";if(($0=="-s-"))print "2";if(($0=="--t"))print "1"}'`"
[ -z "$Auth_Info" ] && return
Num=1
for i in $Auth_Info
do
     [ $Num == 1 ] && File=$i && let Num++ && continue
     [ $Num == 2 ] && User=$i && let Num++ && continue
     [ $Num == 3 ] && Group=$i && let Num++ && continue
     [ $Num == 4 ] && Part=$i && let Num++ && continue
     [ $Num == 5 ] && OwnAu=$i && let Num++ && continue
     [ $Num == 6 ] && GroupAu=$i  && let Num++ && continue
     [ $Num == 7 ] && OtherAu=$i && Num=1 
# 跟上面大同小异,只是多了一个特殊权限$Part而已
    [ ! -e $File ] && continue
    [ $Reco_Type == chown ] && $Reco_Type $User"."$Group $File && continue
    $Reco_Type $Part$OwnAu$GroupAu$OtherAu $File
done
}
# 这个函数是整个恢复模块,其实就是为了主程序逻辑方面看起来稍好一点
recove(){
# 习惯性的cd /,haha!
cd /
# 这个循环就是为了让用户输入必要的信息
while true
do
    echo -e "\n\n"
    read -p "请输入你要恢复属主属组信息还是权限信息(按q退出)(chown或者chmod)" Reco_Type
    
    [ i$Reco_Type == iq ] && return 4
    echo -e "\n\n"
    read -p "请输入你要恢复的目录的绝对路径,输入为空恢复整个文件系统权限信息(按q退出):" Reco_Dir
    echo "请稍后。。。。"
    [ i$Reco_Dir == iq ] && return 4
    
    [[ "$Reco_Type" =~ (chmod|chown) ]] && break
    
done
# 用户输入的是是就对路径,带“/”,但是在备份文件当中没有根的,备份方式决定的。
# 所以呢,将/给取点,让之后的操作可以正常进行
Reco_Dir=`echo $Reco_Dir |sed 's@^/@@'`
# 如果用户输入的是空,那么恢复整个文件系统权限,需要整个备份文件的信息
# 直接使用复制主备份文件,这个子文件在恢复完成之后就被毁掉了,所以,
# 你懂得。
if [ -z $Reco_Dir ];then
   \cp $Back_File ${Back_File}.1
   \cp $Back_File_Part ${Back_File_Part}.1
# 如果用户输入的是指定目录或者文件的权限信息,那么找出相应文件获这目录的权限信息,加以恢复
else
# 每个属性信息都是以“# file:”为开头的,找出以这个为开头的行
# 同时打印这行开始的n行,一般文件属性信息有6行,而特殊权限位的有7行
# 所以,分别处理
    grep -A 5 "^# file: $Reco_Dir" $Back_File  > ${Back_File}.1
    grep -A 6 "^# file: $Reco_Dir" $Back_File_Part > ${Back_File_Part}.1
fi
# 如果用户输入的文件或者目录不存在,那么这两个文件都是空的,返回3,给主程序处理
[ ! -s $Back_File'.1' -a ! -s $Back_File_Part'.1' ] && return 3
# 如果文件不都是空的,走这边,将
recove_handle $Reco_Type
}
# main procces 
# 如果$1 等于-h或者--help那么获取帮助信息,嘿嘿。
[[ $1 =~ (-h|--help) ]] && Help && exit 0
clear
if [ ! -f $Back_File ];then
# 打印提示信息,让用户选择
   echo -ne "\v\v\v\v\v\v\v\v\v\v\v\v备份文件不存在,是否进行备份(默认备份)?输入y或者Y进行备份: "
   
   read sele
   case $sele in
   y|Y|"")
       echo "请稍后。。。。"
# 调用back函数,专门用来备份
       back
# 如果备份完成,打印完成信息
       [ $? == 0 ] && echo -e "\n整个文件系统权限信息备份完毕,文件位置为$Back_File $Back_File_Part\n" &&  exit 0
       echo -e "\n整个文件系统权限信息备份失败,检查用户是否有权限做备份。" && exit 1
       ;;
   
   *)
       echo "文件系统权限信息没有备份,请及时处理!" 
       exit 0;;
     
   esac
else
# 如果备份文件存在也会提示是否备份
   echo -ne "\v\v\v\v\v\v\v\v\v\v\v\v\v\v备份文件已经存在,需要进行进行备份还是恢复? r|R(恢复) b|B(备份): "
   read sele
   case $sele in
   b|B)
       echo "请稍后。。。。。。"
       back
       [ $? == 0 ] && echo -e "\n整个文件系统权限信息重新备份完毕,文件位置为$Back_File $Back_File_Part\n" &&  exit 0 ;;
   r|R)
# 调用恢复函数,由函数的返回结果,打印具体信息
       recove
       case $? in 
       0)
          echo -e "\n/$Reco_Dir 下所有文件权限信息恢复至 `stat $Back_File |awk -F "Modify: " '/Modify/{print $2 }'`\n " 
          exit 0 ;;
       3)
           echo "输入的文件或者目录不存在!格式:如/mnt 应输入mnt,会恢复/mnt下所有的子目录权限!
如果需要恢复/下所有文件的权限信息,请直接回车!";;
       4)
           echo "GoodBey!Beby";;
       esac;;
       
   *)
       echo -e "\n你的选择有误,抱歉!\n";;
   esac
fi

 

 
 
 
posted @ 2016-12-07 08:10  么么哒的小蝌蚪  阅读(6552)  评论(0编辑  收藏  举报