사용자를 삭제하려면 Bash 스크립트를 만들어야 합니다.
우리는 RHEL 버전 4, 5, 6을 사용합니다.
사용자 이름이 Ray4 및 Ray6이고 스크립트 이름이 deal이라고 가정합니다.
이 스크립트의 특정 작업은 다음과 같습니다.
- 사용자가 존재합니까?
- 사용자가 존재하는 경우 사용자의 /home 디렉토리를 백업하고 사용자 이름을 삭제한 후 /root/DeletedUsers에 넣습니다.
- /root/DeletedUsers 디렉터리가 없으면 새로 만듭니다.
- 이 사용자에 대한 방화벽 규칙이 있는 경우 해당 규칙의 결과와 어떤 노드에 대한 결과를 이메일로 보내주십시오.
- 사용자가 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
그러면 필요가 grep
없습니다 sed
. 실제로 그보다 grep
더 빠르다 .sed
grep
그리고 [test]
그 출력그 다음에Invoke sed
, sed
문제가 있는 문자열과 관련된 모든 파일의 삭제가 완료되었을 수 있습니다.
grep
그리고 다시 말하지만, 어떤 이유로 든 정말로 이 작업을 수행하고 싶다면 sed
다음이 더 중요할 것입니다.
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'
위의 내용은 대상 사용자에게 $HOME
사용자 이름의 이름을 딴 in이 있다고 가정합니다. /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
$remove
stderr
위에서 작성한 것과 같은 스크립트를 자신의 컴퓨터에서 실행하고 모든 대상에 연결하면 각 대상에서 자신의 컴퓨터로 연결을 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