Quiero pasar stdin a un script bash a un script python llamado en ese script bash


9

Tengo un script bash que invoca un script python del que quiero alimentar el contenido a filetravés de stdin. Llamando al script bash como:

./script.sh < file

Y los contenidos de script.sh:

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

No tengo idea de qué llenar para ??????pasar el contenido de filedado al script bash como stdin al script python main.py.

Tenga en cuenta que filepuede ser un archivo de texto sustancial y noread es deseable usar bash .

Usar stdin al invocar el script bash es un requisito. Soy flexible para pasar lo que sea main.py.

¿Alguna idea sobre cómo abordar este enigma?

adición

La respuesta de @cas me dejó claro que también necesito explicar en qué contexto trato de usar script.sh.

Quiero usar script.shcomo script de reenvío~/.forward , con el contenido:

|/path/to/script.sh

Qué postfix llama como /path/to/script.sh; el registro es claro al respecto. Una prueba simple con una versión reducida del script de Python, como:

|/path/to/simple/main.py

Demuestra que postfix llama main.pycon el contenido del correo en el stdin. Pero la combinación no parece funcionar.


¿Está utilizando la propia localLDA de postfix o alguna otra cosa, como procmailo deliver? ¿Hay algo en ti ~/.bashrcque pueda perturbar el medio ambiente como se ve main.pycuando se ejecuta desde dentro script.sh? tal vez registre el entorno ejecutando algo como { typeset -p ; echo } >> "/tmp/forward.log"dentro de script.sh.
cas

Respuestas:


15

Asumiendo que su main.pyscript está escrito correctamente para leer desde stdin y que nada en venv/bin/activatelecturas de stdin (*), ??????debería ser "nada en absoluto".

No hay comandos anteriores en el script bash que consuman stdin antes de python, por lo que python comenzará a consumirlo.

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

O haga main.pyejecutable y ejecútelo directamente como ./main.py... funciona igual, de cualquier manera.

(*) si lo hubiera, probablemente no sería capaz de hacer esto en absoluto, sin algo feo como capturar todo el stdin en una variable y luego canalizar o <<<redirigir la variable primero venv/bin/activatey luego main.py.


Para un ejemplo muy obvio de lo que está sucediendo aquí y por qué esto funciona, considere el siguiente script sh kitten.sh:

#!/bin/sh
cat

Simplemente se ejecuta cat, que comienza a leer desde stdin e imprime su entrada en stdout.


55
awww ... el gatito es tan lindo, tiene su propia línea shebang.
cas

Hola @cas Gracias por la extensa respuesta. Y sí, funciona como debería. Extendí mi pregunta para aclarar en qué contexto estoy tratando de usarla y dónde no funciona. Puede ser que este SE sea el foro equivocado para hacer la pregunta.
nanitous

La edición me llevó más de 6 minutos ;-)
nanitous

Si otros comandos anteriores en la secuencia de comandos necesitan consumir stdin (ediciones futuras de la secuencia de comandos, etc.), algunos sistemas operativos tienen nombres de pseudoarchivos que pueden pasarse como marcadores de posición. Bajo muchos sabores de Linux, por ejemplo, /dev/stdinhay un archivo de dispositivo (o un enlace simbólico a ese) que hará lo correcto cuando se lea. La desventaja, por supuesto, es que la portabilidad se limita a los sistemas operativos cuyos nombres especiales conoces, por ejemplo, asignar una variable local al nombre de archivo falso apropiado y luego usar la variable como argumento para python main.py.
Ti Strga

todo el propósito del script del OP es configurar el entorno para python y luego pasar stdin a main.py, por lo que cualquier cosa que hiciera eso sería romperlo.
cas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.