Como criar um script bash executável para esses comandos?

2

Eu desejo criar um script bash executável que executará os seguintes comandos como root, ou seja, usando sudo su

iptables-save | awk '/^[*]/ { print $1 } 
                     /^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
                     /COMMIT/ { print $0; }' | iptables-restore

Minha primeira tentativa de script do bash é a seguinte:

#!/bin/bash
sudo su
iptables-save | awk '/^[*]/ { print $1 } 
                     /^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
                     /COMMIT/ { print $0; }' | iptables-restore
sleep 3;
exit 0

Alguém poderia corrigir o problema acima e torná-lo viável?

    
por user66229 25.05.2014 / 06:56

1 resposta

3

Os scripts do shell não são exatamente o mesmo que digitar em um terminal.
O que vai acontecer aqui é que iptables-save vai esperar que sudo su seja concluído e, em seguida, execute. O que você deseja é executar iptables-save dentro do sudo .

Em segundo lugar, sudo su está entre as categorias de exemplos de 'uso inútil'. O equivalente correto é sudo -i .

Existem 2 abordagens que você pode tomar para resolver isso.

Método 1

sudo -i <<'EOF'
iptables-save | awk '/^[*]/ { print $1 } 
                 /^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
                 /COMMIT/ { print $0; }' | iptables-restore
EOF

Isso basicamente lança um shell de root e envia esse comando através do shell.
O motivo pelo qual não adicionamos apenas sudo na frente dos comandos iptables-save e iptables-restore é que ele lançará 2 sudo s ao mesmo tempo. Isso não funciona bem se os dois acabarem tentando solicitar a senha.
Portanto, essa solução funciona em torno do problema, lançando apenas um único sudo .

Uma linha
Conforme solicitado em seu comentário, você pode fazer isso em uma única linha, mas fica muito mais difícil de ler.

sudo -i sh -c 'iptables-save | awk '\''/^[*]/ { print $1 }; /^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }; /COMMIT/ { print $0; }'\'' | iptables-restore'

Método 2

sudo -v
sudo -n iptables-save | awk '/^[*]/ { print $1 } 
             /^:[A-Z]+ [^-]/ { print $1 " ACCEPT" ; }
             /COMMIT/ { print $0; }' | sudo -n iptables-restore

Esta solução executa sudo pela primeira vez, sem nenhum comando, simplesmente -v . Isso faz com que sudo solicite sua senha se sua sessão expirar. Então, qualquer comando executado dentro dessa janela de expiração da sessão não exigirá uma senha. Portanto, lançar 2 sudo s ao mesmo tempo não é mais um problema, pois nenhum deles solicitará (adicionamos -n para ter certeza absoluta disso. Isso causará um erro se tentar).

    
por 25.05.2014 / 09:29