Je veux passer stdin à un script bash à un script python appelé dans ce script bash

9

J'ai un script bash invoquant un script python dont je veux alimenter le contenu filevia stdin. Appel du script bash comme:

./script.sh < file

Et le contenu de script.sh:

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

Je ne sais pas quoi remplir pour ??????passer le contenu de filegiven au script bash en tant que stdin au script python main.py.

Notez qu'il filepeut s'agir d'un fichier texte substantiel et l'utilisation de bash readn'est pas souhaitable.

L'utilisation de stdin lors de l'appel du script bash est une exigence. Je suis flexible pour passer quoi que ce soit main.py.

Avez-vous des idées sur la façon de résoudre cette énigme?

une addition

La réponse de @cas m'a fait comprendre que je dois également expliquer dans quel contexte j'essaie d'utiliser script.sh.

Je veux utiliser script.shcomme script de transfert dans ~/.forward, avec le contenu:

|/path/to/script.sh

Quel suffixe appelle comme /path/to/script.sh; le journal est clair à ce sujet. Un test simple utilisant une version déguisée du script python, comme:

|/path/to/simple/main.py

Montre que postfix appelle main.pyavec le contenu du courrier sur le stdin. Mais la combinaison ne semble pas fonctionner.

naneux
la source
utilisez-vous le propre localLDA de postfix ou autre chose, comme procmailou deliver? y a-t-il quelque chose dans votre maison ~/.bashrcqui pourrait perturber l'environnement tel que vu par la main.pycourse de l'intérieur script.sh? peut-être enregistrer l'environnement en exécutant quelque chose comme à l' { typeset -p ; echo } >> "/tmp/forward.log"intérieur de script.sh.
cas

Réponses:

15

En supposant que votre main.pyscript est correctement écrit pour lire depuis stdin et que rien dans les venv/bin/activatelectures depuis stdin (*), ??????ne devrait être "rien du tout".

Il n'y a aucune commande précédente dans le script bash qui consommera stdin avant python, donc python commencera à le consommer.

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

Ou rendez main.pyexécutable et exécutez-le directement car ./main.py... fonctionne de la même façon, dans les deux cas.

(*) s'il y en avait, vous ne seriez probablement pas en mesure de le faire, sans quelque chose de laid comme capturer tout stdin dans une variable, puis <<<rediriger ou rediriger la variable en premier venv/bin/activateet ensuite main.py.


Pour un exemple très évident de ce qui se passe ici et pourquoi cela fonctionne, considérez le script sh suivant kitten.sh:

#!/bin/sh
cat

Il s'exécute simplement cat, ce qui commence à lire à partir de stdin et à imprimer son entrée sur stdout.

cas
la source
5
awww ... le chat est si mignon, il a sa propre ligne de shebang.
cas
HI @cas Merci pour la réponse détaillée. Et, oui, cela fonctionne comme il se doit. J'ai étendu ma question pour préciser dans quel contexte j'essaie de l'utiliser et où cela ne fonctionne pas. Peut-être que cette SE n'est pas le bon forum pour poser la question.
nanitous
Le montage m'a pris plus de 6 min ;-)
nanitous
Si d'autres commandes plus tôt dans le script doivent consommer stdin (futures modifications du script, etc.), certains systèmes d'exploitation ont des pseudo-noms de fichiers qui peuvent être transmis comme espaces réservés. Sous de nombreuses versions de Linux, par exemple, se /dev/stdintrouve un fichier de périphérique (ou un lien symbolique vers celui-ci) qui fera la bonne chose lors de la lecture. Le compromis, bien sûr, est que la portabilité est limitée aux systèmes d'exploitation dont vous connaissez les noms spéciaux, par exemple, en affectant une variable locale au faux nom de fichier approprié, puis en utilisant la variable comme argument pour python main.py.
Ti Strga
tout le but du script de l'OP est de configurer l'environnement pour python, puis de passer stdin à main.py, donc tout ce qui a fait cela le briserait.
cas