ユーザーを削除する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/文字列を含む行を検索し2、見つかった場合はアドレス指定された文字列を除くすべての項目を含むようにその行を変更します。以下を削除してくださいただアドレス指定ライン:

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

#OUTPUT#
456

そうする必要はgrepありませんsed。実際にそれgrepより速い。sedgrep そして [test]その出力それからInvoke sedsed問題のある文字列に関連するすべてのファイルの削除が完了した可能性があります。

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ユーザー名の名前が付けられていると仮定しています。/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

これにより、文字列を含む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

関連情報