Eu vi esta linha enquanto lia um blog no IFS que é:
for i in $(<test.txt)
E pensei que $(<test.txt)
imprime o conteúdo do arquivo para STDOUT. Talvez eu esteja errado nisso, mas por curiosidade tentei fazer no shell. Então, peguei um arquivo aleatório chamado array
com dados aleatórios e
Primeiro fiz um cat array
que me deu isso:
amit@C0deDaedalus:~/test$
amit@C0deDaedalus:~/test$ cat array
1) Ottawa Canada 345644
2) Kabul Afghanistan 667345
3) Paris France 214423
4) Moscow Russia 128793
5) Delhi India 142894
E então $(<array)
isso me deu isso:
amit@C0deDaedalus:~/test$ $(<array)
1) Ottawa Ca: command not found
Eu só sei que <
é usado para redirecionamento de entrada, mas não obtendo exatamente o que está sendo interpretado pelo shell como um comando aqui.
Alguém pode explicar o conceito por trás dessa saída estranha no shell?
Atualizar :-
Ao rodar set -x
dá isso:
amit@C0deDaedalus:~/test$ $(<array)
+ '1)' Ottawa Canada 345644 '2)' Kabul Afghanistan 667345 '3)' Paris France 214423 '4)' Moscow Russia 128793 '5)' Delhi India 142894
+ '[' -x /usr/lib/command-not-found ']'
+ /usr/lib/command-not-found -- '1)'
1): command not found
+ return 127
amit@C0deDaedalus:~/test$
A
$(command)
sintaxe é executadacommand
em um ambiente de subshell e se substitui pela saída padrão decommand
. E, como diz o Manual do Bash ,$(< file)
é apenas um equivalente mais rápido de$(cat file)
(embora não seja um recurso POSIX).Portanto, quando você executa
$(<array)
, o Bash realiza essa substituição e usa o primeiro campo como o nome do comando e o restante dos campos como argumentos do comando:Não tenho nenhum
1)
comando/função, então imprime uma mensagem de erro.Mas em seu cenário específico, você está recebendo uma mensagem de erro diferente provavelmente porque modificou a variável IFS:
Editar 1
Meu palpite é que o seu
IFS
foi modificado de alguma forma, então é por isso que seu shell tentou executar1) Ottawa Ca
em vez de1)
. Afinal, você estava lendo umIFS
artigo relacionado a -. Eu não ficaria surpreso se vocêIFS
acabasse com um valor estranho.A
IFS
variável 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 comoread
).O manual do Bash explica este tópico :
Aqui estão alguns exemplos sobre
IFS
o uso de substituição de comandos:Exemplo 1:
Em ambos os casos,
IFS
is<space><tab><newline>
(o valor padrão),var
ishello world
e há umaprintf
instrução. Mas observe que no primeiro caso a divisão de palavras é realizada, enquanto no segundo caso não é (porque as aspas duplas inibem esse comportamento). A divisão de palavras ocorre em expansões sem aspas.Exemplo 2:
Nem
${var}
nem${?}
contém nenhum 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 porqueIFS
pode ser abusado.IFS
pode conter praticamente qualquer valor e é fácil abusar.Exemplo 3:
Isso não tem nada a ver com divisão de palavras, mas observe como podemos usar alguns truques sujos para injetar código.
Perguntas relacionadas: