Por que isso é inconsistente? Eu esperaria aqui docs e aqui strings para ser funcionalmente equivalente ao redirecionamento de entrada de um arquivo.
$ bash --version
GNU bash, version 4.1.2(1)-release (x86_64-unknown-linux-gnu)
...
Saída esperada:
Imprime cada item da lista.
$ for server in $(<servers.txt); do echo ${server}; done
server1
server2
server3
$
Saída inesperada:
Não imprime nada.
$ for server in $(<<EOF
> server1
> server2
> server3
> EOF
> ); do echo ${server}; done
$
Saída inesperada:
Não imprime nada.
$ for server in $(<<<"server1
> server2
> server3"); do echo ${server}; done
$
Edit: Eu segui o bash usando um redirecionador de entrada, e novamente com uma string here. Aqui está a diferença de comportamento entre os dois:
Redirecionador de entrada
$ echo $(<servers.txt)
...
31929 open("servers.txt", O_RDONLY) = 3
31929 read(3, "server1\nserver2\nserver3\n", 128) = 24
31929 write(1, "server1\nserver2\nserver3\n", 24) = 24
...
Isso gera o processo filho 31929, que abre o server.txt como FD 3 e o grava no stdout.
Aqui string
$ echo $(<<<"server1
> server2
> server3")
...
31990 open("/tmp/sh-thd-106091305575", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3
31990 write(3, "server1\nserver2\nserver3", 23) = 23
31990 write(3, "\n", 1) = 1
31990 open("/tmp/sh-thd-106091305575", O_RDONLY) = 4
31990 close(3) = 0
31990 unlink("/tmp/sh-thd-106091305575") = 0
31990 fcntl(0, F_GETFD) = 0
31990 fcntl(0, F_DUPFD, 10) = 10
31990 fcntl(0, F_GETFD) = 0
31990 fcntl(10, F_SETFD, FD_CLOEXEC) = 0
31990 dup2(4, 0) = 0
31990 close(4) = 0
31990 dup2(10, 0) = 0
31990 fcntl(10, F_GETFD) = 0x1 (flags FD_CLOEXEC)
31990 close(10)
...
Várias etapas são realizadas aqui:
- O processo filho 31990 é gerado
- A string aqui é gravada em / tmp / sh-thd-106091305575
- / tmp / sh-thd-106091305575 é aberto como somente leitura (FD 4)
- / tmp / sh-thd-106091305575 está desvinculado (assim, quando o FD 4 for fechado, ele será excluído)
- stdin é enganado para FD 10
- FD 4 (o arquivo temporário contendo nossa string aqui) é enganado para FD 0 (stdin) É onde um processo - neste caso, o subshell bash - atuaria em stdin
- FD 4 é fechado e FD 10 é levado de volta para FD 0
O surpreendente é que isso acontece no exemplo do redirecionador de entrada:
31929 write(1, "server1\nserver2\nserver3\n", 24) = 24
Eu suspeito que o bash tenha um comportamento especial para este caso. Provavelmente precisará cavar a fonte para uma resposta definitiva.