A diferença é que echo
envia uma nova linha no final de sua saída. Não há como "enviar" um EOF.
Qual é a diferença entre a função printf
no bash e a função echo
?
Especificamente, executando:
echo "blah" >/dev/udp/localhost/8125
não enviou o comando "blah" para o servidor escutando em 8125, enquanto
printf "blah" >/dev/udp/localhost/8125
enviou os dados. O printf envia um EOF extra no final de sua saída?
Os comandos echo
e printf
são internos ( printf
é o Bash integrado desde a v2.0.2 (1998)). echo
sempre sai com um status 0 e simplesmente imprime argumentos seguidos por um caractere de fim de linha na saída padrão, enquanto printf
permite a definição de uma cadeia de formatação e fornece um código de status de saída diferente de zero após uma falha. / p>
printf
tem mais controle sobre o formato de saída. Ele pode ser usado para especificar a largura de campo a ser usada para item, bem como várias opções de formatação para números (como qual base de saída usar, se imprimir um expoente, se imprimir um sinal e quantos dígitos serão impressos após o ponto decimal). Isso é feito fornecendo a string de formato, que controla como e onde imprimir os outros argumentos e tem a mesma sintaxe da linguagem C ( %03d
, %e
, %+d
, ...). Isso significa que você deve escapar do símbolo de porcentagem quando não estiver falando sobre formato ( %%
).
Provavelmente, se você adicionar o caractere de nova linha que echo
usa por padrão (exceto quando usar a opção -n
), você obterá o mesmo efeito.
printf "blah\n" >/dev/udp/localhost/8125
Em relação ao desempenho, sempre tive em mente que echo
era mais rápido que printf
porque o último tem que ler a string e formatá-la. Mas testando-os com time
(também embutido) os resultados dizem o contrário:
$ time for i in {1..999999}; do echo "$i" >/dev/null; done
real 0m10.191s
user 0m4.940s
sys 0m1.710s
$ time for i in {1..999999}; do printf "$i" >/dev/null; done
real 0m9.073s
user 0m4.690s
sys 0m1.310s
Dizendo printf
para adicionar caracteres de nova linha, assim como echo
faz por padrão:
$ time for i in {1..999999}; do printf "$i\n" >/dev/null; done
real 0m8.940s
user 0m4.230s
sys 0m1.460s
que é obviamente mais lento do que sem imprimir o \n
, mas ainda mais rápido que echo
.
Aqui é provavelmente a melhor descrição de echo vs printf
Em um nível muito alto .. O printf é como o eco, mas pode ser feito mais formatação.
Para mensagens triviais (sem seqüências de escape, sem opções), echo
é bom. Assim que você precisar de algo mais complexo, você deve usar printf
, que é portátil (ou seja, se comportar da mesma maneira, independentemente do sistema operacional) e permite uma formatação muito melhor, sendo projetado a partir da mesma função de nome C.
Se você quiser chamar echo
em seu exemplo, a maneira correta seria:
echo -n "blah" >/dev/udp/localhost/8125
ou
echo "blah\c" >/dev/udp/localhost/8125
dependendo da implementação de echo
que você usa.
echo
imprime seu argumento seguido por uma nova linha. Com vários argumentos, eles são separados por espaços. Dependendo da variante unix, o shell e as opções de shell, ele também pode interpretar algumas seqüências de escape começando com \
, e pode tratar o primeiro argumento como opções se elas começarem com -
.
printf
interpreta seu primeiro argumento como um formato e argumentos subseqüentes como argumentos para os %
especificadores. Nenhuma nova linha é adicionada, a menos que você especifique uma. No primeiro argumento, todos os caracteres, exceto dois, são interpretados literalmente: %
inicia um especificador printf e \
inicia uma sequência de escape (por exemplo, \n
para um caractere de nova linha).
Como diferentes shells funcionam de maneira diferente, echo "$string"
nem sempre imprime a string especificada mais uma nova linha. Uma maneira confiável de imprimir uma string é printf %s "$string"
. Se você quiser uma nova linha após a string, escreva printf '%s\n' "$string"
.
No seu caso, supondo que blah
não comece com -
ou que contenha %
ou \
, a única diferença entre os dois comandos é que echo
adiciona uma nova linha e printf
não faz.
Se você quiser literalmente imprimir a string "-e", você terá dificuldades em fazer isso com o eco. Eu enfrentei um problema desses recentemente enquanto escrevia um script.
Eu tive que usar o prinf para poder imprimir a string literal "-e".
Tags bash