O que é um here string?
Um here string nada mais é do que uma maneira de transformar uma string na entrada padrão (stdin) de um programa. Normalmente utilizamos essa técnica pegando a string contida em uma variável.
A sintaxe, pegando de uma variável, é a seguinte:
COMMAND <<< "$VAR"
Onde o conteúdo variável $VAR
será colocado na entrada padrão do COMMAND
.
Usar a técnica do here string evita o uso de estruturas como:
# uso desnecessário do echo
echo "$var" | grep padrao
Podemos obter o mesmo resultado usando a sintaxe do here string:
grep padrao <<< "$var"
Na minha opinião, o código fica mais limpo e legível desta forma. Além disso, também temos um ganho de performance.
A explicação para isso está num trecho do manual do bash que fala de Pipelines (tradução livre):
Cada comando em um pipeline é executado em seu próprio subshell, o que é um processo separado (…)
Ou seja, a cada pipe um subshell é inicializado, e isso gera um custo de performance. Principalmente se você estiver fazendo isso dentro de um loop com dezenas/centenas de iterações.
Espero que estes dois fatores (1. código limpo, 2. performance) sejam motivos suficientes para você começar a usar o here string a partir de agora.
Quando não usar here strings
Conforme podemos ver no próprio manual do bash (tradução livre):
O resultado é enviado à entrada padrão do comando, como uma única string e com uma nova linha adicionada ao final
Portanto, em casos onde esse caractere de nova linha não é desejado, não podemos usar o here string. Estes casos são bem raros, mas acontecem.
Eu me deparei com esse problema quando estava trabalhando numa aplicação onde eu precisava calcular o checksum MD5 dos 8 primeiros bytes de um arquivo. Vou ilustrar o problema através do exemplo a seguir:
$ cat texto.txt
conteudo do arquivo
$ head -c8 texto.txt | md5sum
b59853db2f3ef8f156a72e38c30ba7d2 -
$
$ # armazenando o conteúdo em uma variavel
$ variavel=$(head -c8 texto.txt)
$ md5sum <<< "$variavel"
746378123fbe2cbca33ed5d88f35c5bb -
$ # ué! era pra ser igual ao md5 lá de cima!
$
$ # vejamos com o 'echo -n' (sem nova linha no final):
$ echo -n "$variavel" | md5sum
b59853db2f3ef8f156a72e38c30ba7d2 -
$ # agora sim! o checksum é igual! :)
Conforme podemos ver, nas raríssimas situações onde o caracter de nova linha no final da string pode alterar o resultado desejado, o uso de here strings não resolve.
Cuidado com o exagero
Legal, você aprendeu que usando here strings você tem um ganho de performance, mas também não precisa ficar fissurado com isso e usar here strings em toda e qualquer oportunidade.
Entenda que a função dessa técnica é colocar uma string no arquivo de entrada padrão de um comando.
Eu já vi um caso onde a pessoa usou comando <<< $(< arquivo)
. Ou seja, através do redirecionamento no $()
ele colocou o conteúdo de um arquivo numa string para logo em seguida mandar essa string para a entrada padrão do comando
. Neste caso bastava usar simplesmente comando < arquivo
.