Eu quero passar stdin para um script bash para um script python chamado nesse script bash

9

Eu tenho um script bash chamando um script python do qual desejo alimentar o conteúdo filevia stdin. Chamando o script bash como:

./script.sh < file

E o conteúdo de script.sh:

#! /usr/bin/env bash
pushd /some/python/virtual/environment/working/dir
source venv/bin/activate
python main.py ??????
deactivate
popd

Eu não tenho idéia do que preencher para ??????passar o conteúdo do filedado para o script bash como stdin para o script python main.py.

Observe que filepode ser um arquivo de texto substancial e o uso do bash nãoread é desejável.

Usar stdin ao chamar o script bash é um requisito. Sou flexível para passar o que quer que seja main.py.

Alguma idéia lá fora, como lidar com esse enigma?

Adição

A resposta do @cas deixou claro para mim que também preciso explicar em que contexto tento usar script.sh.

Quero usar script.shcomo um script de encaminhamento~/.forward , com o conteúdo:

|/path/to/script.sh

Qual postfix chama como /path/to/script.sh; o log é claro sobre isso. Um teste simples usando uma versão simplificada do script python, como:

|/path/to/simple/main.py

Demonstra que o postfix chama main.pycom o conteúdo do email no stdin. Mas a combinação não parece funcionar.

nanitous
fonte
você está usando o próprio localLDA do postfix ou algo mais, como procmailou deliver? existe algo no seu ~/.bashrcque possa perturbar o meio ambiente, visto main.pyquando executado a partir de dentro script.sh? talvez registre o ambiente executando algo como { typeset -p ; echo } >> "/tmp/forward.log"dentro do script.sh.
cas

Respostas:

15

Supondo que seu main.pyscript esteja corretamente escrito para ler a partir de stdin e que nada nas venv/bin/activateleituras de stdin (*), ??????seja "nada".

Não há comandos anteriores no script bash que consumirão stdin antes do python, portanto, o python começará a consumi-lo.

#/bin/bash
pushd /some/python/virtual/environment/working/dir
source venv/bin/activate
python main.py
deactivate

Ou torne o main.pyexecutável e execute-o diretamente, pois ./main.py... funciona da mesma maneira.

(*) se houvesse, você provavelmente não seria capaz de fazer isso, sem algo feio como capturar todo o stdin em uma variável e, em seguida, canalizar ou <<<redirecionar a variável para a primeira venv/bin/activatee depois main.py.


Para um exemplo muito óbvio do que está acontecendo aqui e por que isso funciona, considere o seguinte script sh kitten.sh:

#!/bin/sh
cat

É executado cat, o que começa a ler do stdin e a imprimir sua entrada no stdout.

cas
fonte
5
awww ... a vaquinha é tão fofa que tem sua própria linha shebang.
cas
HI @cas Obrigado pela resposta extensa. E, sim, funciona como deveria. Estendi minha pergunta para esclarecer em que contexto estou tentando usá-la e onde não funciona. Pode ser que este SE seja o fórum errado para fazer a pergunta.
nanitous 11/09/19
A edição levou-me mais do que 6 min ;-)
nanitous
Se outros comandos anteriores no script precisarem consumir stdin (edições futuras no script, etc.), alguns sistemas operacionais terão pseudo-nomes de arquivos que podem ser passados ​​como espaços reservados. Sob muitos sabores do Linux, por exemplo, /dev/stdinhá um arquivo de dispositivo (ou um link simbólico para tal) que fará a coisa certa quando lida. A desvantagem, é claro, é que a portabilidade é limitada aos sistemas operacionais cujos nomes especiais você conhece, por exemplo, atribuindo uma variável local ao nome de arquivo falso apropriado e, em seguida, usando a variável como argumento para python main.py.
Ti Strga 11/09/19
todo o objetivo do script do OP é configurar o ambiente para python e depois passar stdin para main.py;
cas