Gostaria de redirecionar o conteúdo de um arquivo para ls
a entrada do comando:
ls -l < /home/john/1.txt
onde 1.txt
o conteúdo é apenas:
/etc
Eu esperava ls
listar o conteúdo do arquivo definido em /home/jonh1.txt
- que é /etc
dir, mas parece ignorar o fluxo de entrada - ainda lista o conteúdo do diretório atual em vez de /etc
dir conforme definido no /home/jonh1.txt
arquivo.
Responder1
parece ignorar o fluxo de entrada
Sim. O ls
programanuncausa o fluxo de entrada, porque não foi escrito para ler nada do fluxo de entrada. Isto não é algo que vem automaticamente com qualquer programa Unix – tem que ser implementado separadamente.
Não confunda o fluxo de entrada (stdin) com os argumentos da linha de comando (argv); o primeiro é um fluxo real que pode ser lido linha por linha, enquanto o último é um conjunto simples de palavras somente leitura. No seu caso, ambos estão presentes e contêm dados diferentes.
(Por que não deveria ser automático para todos os programas? Bem, considereorganizarougatoougrepcomo um exemplo. Esses programas aceitam diferentes tipos de valores – nomes de arquivos como argumentos, mas texto como conteúdo stdin. Assim, você pode canalizar qualquer comando para | sort
e ele classifica a entrada. Mas se stdin e linha de comando fossem a mesma coisa, você não poderia mais canalizar nada | sort
porque pensaria que a entrada do canal era uma lista de nomes de arquivos. Ou vice-versa, você não poderia dar nomes de arquivos porque isso apenas classificaria os nomes.)
Para uma abordagem alternativa, consulteesta explicação no StackOverflow(que você já recebeu nos comentários).
Responder2
Tente usar xargs:
xargs ls -l < /home/john/1.txt
Responder3
Se você escrever qualquer programa de linha de comando que receba informações do usuário, verá claramente o que está acontecendo. Se um programa tiver uma instrução read/readLine(idiomas diferentes podem dar a ele um nome diferente), então, o programa solicita a entrada do usuário, então você também pode canalizar ou redirecionar essa entrada usando |
ou<
Se você observar um programa que recebe entrada, verá como com more
ou less
, se digitá-lo sem entrada $more<ENTER>
, ele solicitará entrada. Ao canalizar dados para ele, ele interrompe a solicitação de entrada. Se executarmos o sed sem parâmetros $sed<ENTER>
, certamente ocorrerá um erro e não poderemos fazer $echo abc|sed<ENTER>
nada disso. Mas se o fizermos $sed 's/a/b/'<ENTER>
, ele solicitará informações. E é por isso que echo abc|sed 's/a/b/'<ENTER>
funciona.
Você pode ver isso se escrever um programa tão simples como Hello World, mas que receba informações como se o programa solicitasse uma palavra e se a pessoa digitar 'abc', ele dirá "Hello abc". Você poderá acessar esse programa. Não é necessária nenhuma programação extra para que a tubulação e o redirecionamento de entrada funcionem. Se o programa aceitar entrada de teclado do usuário, a tubulação e o redirecionamento para ele funcionarão e o programa não solicitará entrada.
Responder4
Editar
Como Kamil Maciorowski apontou em um comentário abaixo, o seguinte não é o caminho certo a seguir.
Se
/home/john/1.txt
é garantido que contém exatamente um caminho entãovocê definitivamente deveria colocar aspas duplas. Se o arquivo puder conter mais de um caminho e você confiar deliberadamente na divisão de palavras, então esta não é a maneira correta de fornecer caminhos arbitrários.
Postagem original (mau exemplo)
Você pode usar o seguinte:
ls -l $(cat /home/john/1.txt)
Veja > man bash
a seçãoSubstituição de comando.