删除用户的 Bash 脚本

删除用户的 Bash 脚本

我需要创建一个 Bash 脚本来删除用户。
我们使用 RHEL 版本 4、5 和 6。
假设用户名是 Ray4 和 Ray6,脚本名称是 deal。
该脚本的具体任务是:

  1. 用户是否存在?
  2. 如果用户存在,备份该用户的/home目录,删除用户名并放置在/root/DeletedUsers中
  3. 如果 /root/DeletedUsers 目录不存在,请创建它。
  4. 如果该用户存在任何防火墙规则,请通过电子邮件将这些规则的结果以及在哪些节点上的结果发送给我。
  5. 如果sudoers中存在该用户,不要删除,而是注释掉。

这是我到目前为止所拥有的。我想在 RHN Satellite 中运行它之前确保它有效。进行建议的更改后。这是我现在遇到的新错误。

[root@localhost bin]# ./deal
./deal: line 7: [[!: command not found
Usage: userdel [options] LOGIN

Options:
  -f, --force                   force removal of files,
                                even if not owned by user
  -h, --help                    display this help message and exit
  -r, --remove                  remove home directory and mail spool
  -Z, --selinux-user            remove SELinux user from SELinux user mapping

Usage: userdel [options] LOGIN

Options:
  -f, --force                   force removal of files,
                                even if not owned by user
  -h, --help                    display this help message and exit
  -r, --remove                  remove home directory and mail spool
  -Z, --selinux-user            remove SELinux user from SELinux user mapping

Null message body; hope that's ok
./deal: line 22: [: -me: binary operator expected



This is source code:
[root@localhost bin]# cat -n deal

 1  #!/bin/bash
 2  
 3  count=$(egrep -c Ray[46] /etc/passwd)
 4  firewall=$(grep -c "192.168.5.5" /etc/sysconfig/iptables)
 5  doers=$(egrep -c Ray[46] /etc/sudoers)
 6  
 7  if [[! -d /root/DeletedUsers]]
 8  then mkdir /root/DeletedUsers
 9  
10  fi
11  
12  cp -Rf /home/Ray[46] /root/DeletedUsers
13  userdel -rf Ray [4]
14  userdel -rf Ray [6]
15  
16  if [ $firewall -ne 0 ]
17  
18  then mail -s "$firewallrulesexist" emailaddress < /dev/null
19  
20  fi
21  
22  if [ $doers -me 0 ]
23  then sed ^Ray[46] /#/i
24  
25  EOF
26  fi

答案1

我建议您用来getent检查用户是否存在。这个脚本应该可以帮助你。

##Check if the user exists using getent command
user_exists=$(getent passwd $1)

##If the user doesn't exist, we need not perform the backup. 

if [ -z "$user_exists" ] 
then
        echo "User $1 does not exist"
else
        cd /root
        #Incorporating derobert's suggestion here. 
        mkdir -p "DeletedUsers"
        ##Use tar or rsync to do the backup as cp will be inefficient.
        tar czvf "$1".tar.gz /home/"$1"
        firewall=$(grep -c "192.168.5.5" /etc/sysconfig/iptables)
        doers=$(egrep -c "$1" /etc/sudoers)
        userdel -rf "$1"
        if [ $firewall -ne 0 ]
        then 
            mail -s "$firewallrulesexist" emailaddress < /dev/null
        fi
        if [ $doers -ne 0 ]
        then 
            sed ^"$1" /#/i
        fi
fi

您可以调用该脚本,./deal ray[4]然后如果您需要为另一个用户运行,您可以使用 来调用它./deal ray[6]。我尚未在我的系统中测试该脚本,但这应该可以帮助您,以防万一您将来需要删除任何其他用户,您不需要修改脚本,而是使用用户名作为参数调用脚本。

编辑

根据 derobert 的建议,如果使用-p标志,则可以省略目录测试。

答案2

如果Ray[46]确实是唯一的,那么脚本中的几乎每个测试都是多余的。

printf %s\\n 123 456 | sed '/2/s///'

#OUTPUT#
13
456

上面的代码将扫描其输入以查找包含/addressed/string 的任何行2,并且如果找到,将仅更改该行以包含除寻址字符串之外的所有内容。下面简单删除仅有的寻址行:

printf %s\\n 123 456 | sed '/2/d'

#OUTPUT#
456

那么grepsed没有必要了。确实,grep比 更快sed,但在调用所需的时间grep [test]它的输出然后invoke sedsed可能已经完成清除所有有问题字符串的相关文件。

话又说回来,如果您出于某种原因确实想要这样做grepsed那么以下内容会更切题:

remove=string ; for f in $(grep -l "$remove" $file_list) ; do 
    printf %s "$(sed "/$remove/s///" "$f")" >"$f" ; done

或者使用 GNU sed

sed -i "/$remove/s///" $(grep -l "$remove" $file_list)

如上所述,mkdir -p仅在必要时才创建目标目录,因此这应该足够了:

mkdir -p /root/DeletedUsers ; mv /home/$string "$_"

您甚至可以获取所有日志,以准确查看仅在发生某些情况的机器上所做的事情:

#ensure $tgt dir exists
mkdir -p ${tgt=/root/DeletedUsers}
#handles Ray4 and Ray6 cases on a single machine
for remove in /home/Ray[46] ; do hostname #print hostname
#nothing happens unless user's $HOME exists
    cd "$remove" 2>/dev/null || { 
        echo "No $remove found here."
        break
    }
#get out of user's $HOME and mv it
    cd - ; mv -v "$remove" "$tgt"
#strip $remove to only username then userdel it
    remove=${remove##*/} 
    userdel -rf $remove
#if $remove in /etc/sudoers comment file's line and and copy change to stderr
    sed -nei "/$remove/{!p;b};s/^/#/p" /etc/sudoers \
        -ne "s/^/sudoers change: /w /dev/stderr" 
#print all iptables lines containing string $remove
    grep "$remove" /etc/sys/config/iptables |
#for each rule found append a noticeable marker line
        sed "a--- "$(hostname)"firewall found"
#finish for statement and pipe all to remote cat to append to log    
done 2>&1 | ssh you@host 'cat >>~/Raydel.log'

上面假设您的目标用户有一个以用户的用户名命名的$HOMEin 。/home如果假设正确,它只会在注册了目标用户用户名的任何计算机上执行操作。

grep如果您不需要做同样的事情,tee也可以省略。只需将sed行更改为:

for f in $file_list ; do 
    sed -ni "/$remove/{h;s///};p;\$!b;x;/$remove/s|.*|$f|w /dev/stderr" "$f"
done

这将用包含 string 的sed's每个新行覆盖保留空间。当完成扫描并到达最后一行时,它会切换到保留空间,并且,如果它发现任何引用,则会将文件名写入.sed"$remove"sed's$removestderr

如果你从你自己的机器上运行一个像我上面写的那样的脚本,并且你ssh连接到所有目标,那么你就不必打开ssh从每个目标到你自己的机器的连接 - 你已经在那里了。您可以删除最后一个|pipe及其后面的所有内容,然后执行以下操作:

script=$(cat <<\SCRIPT
#body of the script I wrote above less the |pipe and all that followed
SCRIPT
) 
for host in $hosts ; do ssh you@$host "$script" ; done >>~/Raydel.log

相关内容