A sintaxe $(command) executa command em um ambiente de subshell e substitui a saída padrão de command . E, como o Bash Manual diz , $(< file) é apenas um equivalente mais rápido de $(cat file) (isso não é um recurso POSIX, no entanto).
Portanto, quando você executa $(<array) , o Bash realiza essa substituição, então ele usa o primeiro campo como o nome do comando e o restante dos campos como argumentos do comando:
$ $(<array)
1): command not found
Eu não tenho nenhum comando / função 1) , então ele imprime uma mensagem de erro.
Mas, no seu cenário específico, você está recebendo uma mensagem de erro diferente, provavelmente porque você modificou a variável IFS:
$ IFS=n; $(<array)
1) Ottawa Ca: command not found
Editar 1
Meu palpite é que seu IFS foi modificado de alguma forma, por isso seu shell tentou executar 1) Ottawa Ca em vez de 1) . Afinal, você estava lendo um artigo relacionado a IFS . Eu não ficaria surpreso se o seu IFS tivesse um valor estranho.
A variável IFS controla o que é conhecido como divisão de palavras ou divisão de campos . Ele basicamente define como os dados serão analisados pelo shell em um contexto de expansão (ou por outros comandos como read ).
Manual do Bash explica este tópico :
3.5.7 Word Splitting
The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting.
The shell treats each character of
$IFSas a delimiter, and splits the results of the other expansions into words using these characters as field terminators. IfIFSis unset, or its value is exactly<space><tab><newline>, the default, then sequences of<space>,<tab>, and<newline>at the beginning and end of the results of the previous expansions are ignored, and any sequence ofIFScharacters not at the beginning or end serves to delimit words. IfIFShas a value other than the default, then sequences of the whitespace charactersspace,tab, andnewlineare ignored at the beginning and end of the word, as long as the whitespace character is in the value ofIFS(anIFSwhitespace character). Any character inIFSthat is notIFSwhitespace, along with any adjacentIFSwhitespace characters, delimits a field. A sequence ofIFSwhitespace characters is also treated as a delimiter. If the value ofIFSis null, no word splitting occurs.Explicit null arguments (
""or'') are retained and passed to commands as empty strings. Unquoted implicit null arguments, resulting from the expansion of parameters that have no values, are removed. If a parameter with no value is expanded within double quotes, a null argument results and is retained and passed to a command as an empty string. When a quoted null argument appears as part of a word whose expansion is non-null, the null argument is removed. That is, the word-d''becomes-dafter word splitting and null argument removal.Note that if no expansion occurs, no splitting is performed.
Aqui estão alguns exemplos sobre IFS e uso de substituição de comandos:
Exemplo 1:
$ IFS=$' \t\n'; var='hello world'; printf '[%s]\n' ${var}
[hello]
[world]
$ IFS=$' \t\n'; var='hello world'; printf '[%s]\n' "${var}"
[hello world]
Em ambos os casos, IFS é <space><tab><newline> (o valor padrão), var é hello world e há uma declaração printf . Mas observe que no primeiro caso a divisão de palavras é executada, enquanto no segundo caso não é (porque aspas duplas inibem esse comportamento). A divisão de palavras ocorre em expansões não citadas.
Exemplo 2:
$ IFS='x'; var='fooxbar'; printf '[%s]\n' ${var}
[foo]
[bar]
$ IFS='2'; (exit 123); printf '[%s]\n' ${?}
[1]
[3]
Nem ${var} nem ${?} contêm qualquer caractere de espaço em branco, portanto, pode-se pensar que a divisão de palavras não seria um problema nesses casos. Mas isso não é verdade porque IFS pode ser abusado. IFS pode conter praticamente qualquer valor e é fácil abusar.
Exemplo 3:
$ $(echo uname)
Linux
$ $(xxd -p -r <<< 64617465202d75)
Sat Apr 28 12:46:49 UTC 2018
$ var='echo foo; echo bar'; eval "$(echo "${var}")"
foo
bar
Isso não tem nada a ver com a divisão de palavras, mas observe como podemos usar alguns truques sujos para injetar código.
Perguntas relacionadas: