Vamos ver o pipeline:
/sbin/iptables-save -t filter |
grep -- "-A INPUT" |
grep -v "fail2ban-\|f2b-" |
sed -e "s#^-A#apply_rule /sbin/iptables -D#g" |
xargs -0 echo -e "'declare -f apply_rule'\n" |
/bin/bash
iptables
gera uma lista de regras, uma regra por linha. Em outras palavras, cada regra é separada por um caractere de nova linha, \n
. Com as opções mostradas, os comandos grep
e sed
estão processando sua entrada uma linha por vez. Em outras palavras, eles também estão esperando entrada separada por nova linha e produzindo saída separada por nova linha. No entanto, xargs -0
está esperando uma entrada separada. Como a saída dos comandos precedidos não contém nenhum caractere nul, xargs
tenta ler todos os seus stdin de uma só vez como um único item. É por isso que gera a mensagem de erro "linha de argumento longa demais".
A solução é informar xargs
para esperar entrada separada por nova linha. Para isso, adicionamos a opção -d '\n'
. No entanto, também queremos processar apenas uma linha por vez. Para fazer isso, precisamos especificar -n1
. Colocando tudo isso junto:
/sbin/iptables-save -t filter |
grep -- "-A INPUT" |
grep -v "fail2ban-\|f2b-" |
sed -e "s#^-A#apply_rule /sbin/iptables -D#g" |
xargs -n1 -d '\n' echo -e "'declare -f apply_rule'\n" |
/bin/bash
Documentação
De man xargs
:
-d delim
Input items are terminated by the specified character. Quotes and backslash are not special; every character in the input is taken literally. Disables the end-of-file string, which is treated like any other argument. This can be used when the input consists of simply newline-separated items, although it is almost always better to design your program to use --null where this is possible. The specified delimiter may be a single character, a C-style character escape such as \n, or an octal or hexadecimal escape code. Octal and hexadecimal escape codes are understood as for the printf command. Multibyte characters are not supported.-n max-args
Use at most max-args arguments per command line. Fewer than max-args arguments will be used if the size (see the -s option) is exceeded, unless the -x option is given, in which case xargs will exit.