Passar texto para o programa esperando um arquivo

21

Relacionado a uma pergunta que fiz no Stack Overflow: Passando várias linhas de código para wsadmin.sh? .

Eu tenho, como uma string, algumas linhas de entrada que preciso inserir em um comando. O comando, no entanto, só aceita um arquivo cheio de entrada.

Existe alguma maneira de armazenar as linhas em um arquivo ou pipe temporário que nunca seja gravado no disco e, em seguida, o insira diretamente no programa?

Como faço para adquirir o tubo, alimentando a entrada nele, passando o tubo para o comando e depois me livrando do tubo?

    
por ArtOfWarfare 13.07.2015 / 05:05

4 respostas

20

Outra solução é usar Substituição de Processo no Bash. Se o seu sistema tiver pipes nomeados, você poderá usar esse recurso.

É usado assim:

program_expecting_a_file <(list)

em que list é uma sequência de comandos shell (na verdade, pipelines; os detalhes completos são aqui ). list será executado e sua saída será conectada ao pipe. O nome do pipe é então passado para o seu programa.

NOTA: os espaços não são permitidos entre < e ( .

(A outra substituição >(list) também funciona como esperado).

No seu caso específico, você poderia usar

program_expecting_a_file <(echo "$your_strings")

embora você possa achar a solução do @ meuh mais elegante.

Atualização: muitos exemplos de uso podem ser encontrados no Guia Avançado de Script Bash .

    
por 13.07.2015 / 10:24
9

Você pode usar um bash aqui-doc . Por exemplo,

$ cat -n <<<'a
> b'
 1  a
 2  b

Se você tem algo em uma variável bash você também pode interpolar: por exemplo, <<<"path is $PATH" .

Se o seu comando insistir em um nome de arquivo, você poderá atribuir /dev/stdin . Por exemplo:

$ sed -f /dev/stdin <<<'s/a/b/'

produz a saída: s/b/b/ .

    
por 13.07.2015 / 09:15
6

Dependendo do que está no script, você pode poder usar o nome do arquivo especial - (menos) que significa stdin

$ mycmd -
Line 1
Line 2
^D

Outro método que pode funcionar para você é abrir o arquivo /dev/fd/0 , que novamente significa stdin .

Uma terceira opção pode ser criar um FIFO (First In First Out). Isso é como um arquivo, mas tem duas finalidades: você escreve para um lado e lê o outro.

-- Process 1 --                  -- Process 2 --
$ mkfifo foo
$ cat foo
<waits>                          $ echo hello > foo
hello                            $
$ rm foo
    
por 13.07.2015 / 10:13
3

Há outra opção semelhante à solução mycmd - , mas mesmo para programas que não lidam com - especificamente:

$ mycmd /dev/stdin
Line 1
Line 2
^D

/dev/stdin parece estar relacionado ao sistema operacional e funciona para mim no Debian GNU / Linux, mas não sei onde mais ele funcionará também.

    
por 13.07.2015 / 18:13