| Subcribe via RSS

chroot 环境下让普通用户修改配置文件

6月 26th, 2008 | No Comments | Posted in shell < by Martian Guo >

以前写的一个脚本,因为有一个项目要求让普通用户修改一些配置文件,而不能让他们有root权限。首先想到的是给这个用户sudo 权限用来执行一个脚本调用vi编辑器,而在vi中是可以直接调用系统命令的,因此这样做并不可靠。我想到了在脚本控制下给vi编辑器一个chroot环境,当vi修改完配置文件后,通过脚本控制复制到实际路径中替换掉旧文件并且可以备份每次修改的diff。下面是我写的一个脚本。介绍一下:
首先设置一个vi的chroot环境,主要程序文件,实际vim依赖哪些so可以用命令 ldd vim 来获取到,可以从相应实际目录中拷贝过来。

./
./bin
./bin/vim
./tmp
./etc
./etc/vimrc
./lib
./lib/ld-linux.so.2
./lib/libdl.so.2
./lib/libselinux.so.1
./lib/libgpm.so.1
./lib/libattr.so.1
./lib/libnsl.so.1
./lib/libc.so.6
./lib/libpthread.so.0
./lib/libncurses.so.5
./lib/libresolv.so.2
./lib/libacl.so.1
./lib/libcrypt.so.1
./lib/libperl.so
./lib/libtermcap.so.2
./lib/libm.so.6
./lib/libutil.so.1
./root
./root/.viminfo

下面是脚本,主要功能:自动搜索特定目录下的文件,修改后自动备份和随时回滚的功能,脚本写的很简单,没什么可说的。当然,你肯定又会说了,何必这么麻烦呢,直接把那些配置文件的修改权给这个用户不就好了吗?如果你非要这样也我也没有办法,这里只是提供这样一种方法,到底要怎么实现怎么做要看具体情况。

#!/bin/sh
#################################################
# File edit&backup&restore tools for sudo user                                   #
# martian <martian2008@gmail.com>                                               #
#################################################
if [ "$UID" != 0 ];then
echo access denied
exit  1
fi
chroot="/usr/local/chroot_vim"        # chroot环境路径
backup="/usr/local/configfile_back"  #  备份文件保存目录
path=(/usr/local/tomcat6/conf /usr/local/httpd/conf /usr/local/php/etc)
# 有权限修改配置文件的目录
 
USAGE="Usage: `basename $0` [OPTION]... {FileName} \n  -e Edit File \n  \
-r Restore File
\n"
 
if [ "$#" -eq 0 ] ;then
        
echo -e "${USAGE}"
        
exit 1
fi
get_char()
{
        
SAVEDSTTY=`stty -g`
        
stty -echo
        
stty raw
        
dd if=/dev/tty bs=1 count=1 2> /dev/null
        
stty -raw
        
stty echo
        
stty $SAVEDSTTY
}
 
answer()
{
        
ANSWER=""
        
while [[ "$ANSWER" != "y" ]] && [[  "$ANSWER" != "Y" ]]
        
do
        
echo -en "Do you want to "
        
echo -en "\\033[0;35m"
        
echo -en "$info"
        
echo -en "\\033[0;38m"
        
echo " this File? (y/n)"
        
read ANSWER
        
case $ANSWER in
              
(y|Y) return 0 ;;
              
(n|N) return 1 ;;
               *)
continue;
        
esac
        
done
}
select_diff()
{
        
N=""
        
read N
        
until [[ $N =~ ^[0-9]+$ ]]   # bash 3.0
        
do
        
echo -n "Please type one number:"
        
read N
        
done
}
 
while getopts e:rOPTION;
do
        
case "$OPTION" in
        
e) info="Edit"
          
F="$OPTARG";;
        
r) info="Restore"
          
F="$OPTARG";;
        \?)
echo -e $USEAGE
            
exit 1
        
esac
done
if [ -n "$F" ];then
for filedir in ${path[*]}
do
 
for f in `/usr/bin/find "$filedir" -type f -name  "$F"`
 
do
        
echo
        
echo -en "\\033[0;35m"
        
echo -en "$info"
        
echo -en "\\033[0;38m"
        
echo -en " File "
        
echo -en "\\033[0;36m"
        
echo "$f ..."
        
echo -en "\\033[0;38m"
        
answer
        
if [ "$?" == 0 ];then
          
filename="`echo "$f" |sed 's#/#\|#g'`"
          
if [ "$info" == "Restore" ];then
                
f1=(`/usr/bin/find "$backup"/"$filename".diff.* -xdev 2>/dev/null `)
                
echo -ne "Found "
                
echo -ne "\\033[0;35m"
                
echo -ne ${#f1[*]}
                
echo -ne "\\033[0;38m"
                
echo " Diff File"
                
if [ "${#f1[*]}" == 0 ];then
                  
echo "Skip..."
                
else
                  
i=${#f1[*]}
                  
for f4 in ${f1[*]}
                  
do
                        
echo -ne "`/bin/basename $f4` "
                        
echo `ls -l "$f4" |awk '{print $6, $7, $8}'`
                  
done
                  
echo -n "Please type one number to Restore [ ${#f1[*]}-1 ]:"
                  
select_diff
                  
echo -ne "Your Select "
                  
echo -ne "\\033[0;35m"
                  
echo -ne "$N"
                  
echo -ne "\\033[0;38m"
                  
echo " to Restore"
                  
pushd "`/usr/bin/dirname $f`" >/dev/null
                  
until [ $N -gt $i ]
                  
do
 
                        
i=$((i-1))
                        
echo "Process File ${f1[$i]}......"
                      
/usr/bin/patch  <${f1[$i]}
                        
if [ "$?" == 0 ];then
                      
/bin/rm ${f1[$i]}
                        
fi
                  
done
                  
popd >/dev/null 2>&1
                
fi
        
else
      
/bin/cp -a "$f" "$chroot"/tmp/"$filename"
      
/usr/sbin/chroot "$chroot" /bin/vim /tmp/"$filename"
      
/usr/bin/diff -Nu  "$chroot"/tmp/"$filename"  "$f"  \
                                >
"$chroot"/tmp/"$filename".diff
        
if [ "$?" != 0 ];then
                
echo -n "Backup Confilg File..."
                
f2="$backup"/"$filename".diff
                
f1=(`/usr/bin/find $f2.* -xdev 2>/dev/null `)
                
i=${#f1[*]}
                
i=$((i+1))
                
echo $i
              
/bin/mv "$chroot"/tmp/"$filename".diff "$f2".$i
                
echo done
                
echo -n "Saveing... Press any key to continue..."
              
/bin/cp -a "$chroot"/tmp/"$filename" "$f"
                
echo done
                
char=`get_char`
        
fi
        
fi
    
fi
 
done
done
fi
阅读内文 Tags: , ,

用vim转换M$文本中的换行符^M

6月 19th, 2008 | 4 Comments | Posted in Linux < by Martian Guo >

在DOS/Windows里,文本文件的换行符为\r\n,而在*nix系统里则为\n,所以DOS/Windows里编辑过的文本文件到了*nix里,每一行都多了个^M。删掉该字符可以在VI里用下面的方法试试

:% s/\r//g

:% s/^M//g
注意 ^M 的输入用? Ctrl+v,再按回车,或者是 Ctrl+v, Ctrl+m。

阅读内文 Tags: