Em:
cat test | xargs -I% bash -c 'echo % $1 $2;'
$1 e $2 são passados como sequências literais no argumento para bash -c , que é o script embutido. E % também será expandido nesse script, portanto, tratado como código shell. Portanto, por exemplo, se test contiver ;reboot; , isso fará com que ele chame o comando reboot .
Você não está transmitindo argumentos para o script in-line, portanto, $1 , $2 estará vazio.
Você poderia fazer:
< test xargs -I% bash -c 'echo "$1" "$2" "$3"' bash % "$1" "$2"
Para encaminhar o argumento do seu script para o script in-line, mas se $1 ou $2 também contiverem % caracteres, eles também serão expandidos em xargs .
Você pode usar o ambiente para passar esses valores:
< test PARAM1=$1 PARAM2=$2 xargs -I% bash -c '
echo "$1" "$PARAM1" "$PARAM2"' bash %
Observe também que xargs faz algum processamento de cotação na entrada, se você quiser que o conteúdo bruto de cada linha seja passado na íntegra, não é isso que você usaria. Com o GNU xargs , você poderia fazer:
< test xargs -d '\n' -n 1 bash -c 'echo "$3" "$1" "$2"' bash "$1" "$2"
Além disso, não se esqueça de citar suas variáveis. printf é mais confiável que echo , mas lembre-se que o primeiro argumento é o formato , então não deve ser variável .