Eu tenho a seguinte função bash:
function exe {
echo -e "Execute: $1"
# Loops every 3s, outputting '...' until command finished executing
LOOP=0
while true;
do
if ! [ $LOOP == 0 ]; then echo -e "..."; fi;
sleep 3;
LOOP=$LOOP+1
done & ERROR="$($2 2>&1)" # Execute the command and capture output to variable
status=$?
kill $!; trap 'kill $!' SIGTERM
if [ $status -ne 0 ];
then
echo -e "✖ Error" >&2
echo -e "$ERROR" >&2
else
echo -e "✔ Success"
fi
return $status
}
A intenção é chamá-lo da seguinte forma:
exe "Update apt indexes" \
"sudo apt-get update"
Quais resultados:
Execute: Update apt indexes
...
...
...
...
✔ Success
Isso funciona corretamente, exceto quando uma string entre aspas é usada como um parâmetro no comando passado.
Por exemplo, o seguinte não funciona:
exe "Create self signed certificate" \
"sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt -subj \"/C=GB/ST=London/L=London/O=Company Ltd/OU=IT Department/CN=dev.domain.local\""
set -x revela que o comando acima é transformado no seguinte para execução:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt -subj '"/C=GB/ST=London/L=London/O=Confetti' Celebrations Ltd/OU=IT 'Department/CN=dev.sign-in.confetti.local"'
Parece que pegou um número de aspas simples e torna o comando ineficaz.
Eu gostaria de uma versão que não tenha essa limitação. Alguma idéia?
===============
Meu código final, após as sugestões e algumas outras correções de bugs, é:
exe () {
echo -e "Execute: $1"
LOOP=0
while true;
do
if ! [ $LOOP == 0 ]; then echo -e "..."; fi;
sleep 3;
LOOP=$((LOOP+1))
done & ERROR=$("${@:2}" 2>&1)
status=$?
kill $!; trap 'kill $!' SIGTERM
if [ $status -ne 0 ];
then
echo -e "✖ Error" >&2
echo -e "$ERROR" >&2
else
echo -e "✔ Success"
fi
return $status
}
A função destina-se como um 'embelezador' para um script de shell de provisionamento vagrant e pode ser chamado como
exe "Update apt indexes" sudo apt-get update
A saída aparece como
Execute: Update apt indexes
...
...
...
...
✔ Success
Comandos que duram menos de 3 segundos não veem pontos de saída de progresso
A menos que haja um erro, quando você receber um status de erro de volta e a saída completa do comando.
A principal intenção é livrar os scripts de provisionamento vagrant das linhas vermelhas mostradas ao enviar mensagens para stderr. Muitos comandos geram corretamente as informações para o stderr, uma vez que se destinam a mensagens que não devem ser canalizadas para outros comandos. Mensagens de impressão do Vagrant para stdout como Isso deixa um número de mensagens de provisionamento que se parecem com erros, mas não são.
Esta função não imprime para stderr, a menos que o comando executado retorne um status diferente de zero. Isso significa que, a menos que um comando indique uma falha, você não verá mensagens vermelhas. Quando um comando indicou falha com uma mensagem diferente de zero, então nós enviamos a saída completa do comando para stderr, dando linhas vermelhas.
Torna o aprovisionamento de vagabundos com um shell script muito mais ordenado e significa que realmente podemos olhar para as mensagens vermelhas sabendo que elas significam algo.
A função completa para usar com vagrant, incluindo um pouco de fluff visual que deixei de fora nos trechos acima, pode ser vista aqui: link
Exemplo de saída usando a função exe, sem erros:
Exemplodesaídausandoafunçãoexe,comerro:
Saídapadrãodaexecuçãodecomandosdiretamente,semerrosreais: