Se Ray[46]
for seguramente único, praticamente todos os testes no seu script são redundantes.
printf %s\n 123 456 | sed '/2/s///'
#OUTPUT#
13
456
O texto acima varrerá sua entrada para qualquer linha que contenha /addressed/
string 2
e, se encontrada, alterará apenas essa linha para conter tudo, menos a string endereçada. Os itens a seguir simplesmente excluem apenas as linhas endereçadas :
printf %s\n 123 456 | sed '/2/d'
#OUTPUT#
456
Portanto, grep
then sed
não é necessário. Verdadeiro, grep
é mais rápido que sed
, mas no tempo que leva para invocar grep
e [test]
sua saída então invocar sed
, sed
provavelmente já teria terminado de limpar todos os arquivos em questão da cadeia incorreta.
Então, novamente, se você quiser grep
then sed
por qualquer motivo, o seguinte seria muito mais direto ao ponto:
remove=string ; for f in $(grep -l "$remove" $file_list) ; do
printf %s "$(sed "/$remove/s///" "$f")" >"$f" ; done
Ou com o GNU sed
:
sed -i "/$remove/s///" $(grep -l "$remove" $file_list)
E, como mencionado acima, mkdir -p
cria um diretório de destino apenas se necessário, portanto, isso deve ser suficiente:
mkdir -p /root/DeletedUsers ; mv /home/$string "$_"
Você pode até obter um registro de tudo para analisar exatamente o que foi feito apenas nessas máquinas. Ocorreu algo:
#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'
Isso pressupõe que o usuário de destino tenha um $HOME
em /home
com o nome de usuário do usuário. Se a suposição estiver correta, ela só executará ações em qualquer máquina na qual o nome de usuário do usuário-alvo esteja registrado.
Para fazer o mesmo sem grep
, você também pode deixar tee
. Basta alterar a linha sed
para:
for f in $file_list ; do
sed -ni "/$remove/{h;s///};p;\$!b;x;/$remove/s|.*|$f|w /dev/stderr" "$f"
done
Isso substituirá sed's
holdpace por cada nova linha sed
localizada contendo a string "$remove"
. Quando sed's
passar pela varredura e chegar na última linha, ele alternará para o espaço de suspensão e, se encontrar alguma referência a $remove
, gravará o nome do arquivo em stderr
.
Se você executar um script como o que escrevi acima em sua própria máquina e você ssh
em todos os destinos, não será necessário abrir uma conexão ssh
de cada um deles de volta para o seu próprio máquina - você já está lá. Você pode remover o último |pipe
e tudo que o segue e fazer isso:
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