Ich möchte stdin an ein Bash-Skript an ein Python-Skript übergeben, das in diesem Bash-Skript aufgerufen wird

9

Ich habe ein Bash-Skript, das ein Python-Skript aufruft, dessen Inhalt ich fileüber stdin füttern möchte . Rufen Sie das Bash-Skript wie folgt auf:

./script.sh < file

Und der Inhalt von script.sh:

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

Ich habe keine Ahnung, was ich ausfüllen soll ??????, um den Inhalt von fileangegeben an das Bash-Skript als Standard an das Python-Skript zu übergeben main.py.

Beachten Sie, dass filebash eine wesentliche Textdatei und verwendet werden kann readist nicht wünschenswert.

Die Verwendung von stdin beim Aufrufen des Bash-Skripts ist erforderlich. Ich bin flexibel, um alles weiterzugeben main.py.

Irgendwelche Ideen, wie man dieses Rätsel lösen kann?

Zusatz

Die Antwort von @cas machte mir klar, dass ich auch erklären muss, in welchem ​​Kontext ich versuche zu verwenden script.sh.

Ich möchte script.shals Weiterleitung verwenden in verwenden ~/.forward, mit dem Inhalt:

|/path/to/script.sh

Welches Postfix heißt /path/to/script.sh ; Das Protokoll ist darüber klar. Ein einfacher Test mit einer verkleideten Version des Python-Skripts, wie:

|/path/to/simple/main.py

Demonstriert, dass Postfix aufruft main.py mit dem Inhalt der Mail auf dem Standard aufruft. Aber die Kombination scheint nicht zu funktionieren.

nanitous
quelle
Verwenden Sie die eigene localLDA von Postfix oder etwas anderes, wie procmailoder deliver? Gibt es irgendetwas in dir, ~/.bashrcdas die Umgebung stören könnte, main.pywenn du von innen script.shrennst? Vielleicht protokollieren Sie die Umgebung, indem Sie etwas wie { typeset -p ; echo } >> "/tmp/forward.log"in script.sh ausführen.
Cas

Antworten:

15

Angenommen, Ihr main.pySkript ist korrekt geschrieben, um von stdin zu lesen, und nichts in venv/bin/activateliest von stdin (*), ??????sollte "überhaupt nichts" sein.

Es gibt keine vorherigen Befehle im Bash-Skript, die stdin vor Python verbrauchen, daher beginnt Python nur damit, es zu verbrauchen.

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

Oder machen Sie eine main.pyausführbare Datei und führen Sie sie direkt aus, da ./main.py... in beiden Fällen genauso funktioniert.

(*) , Wenn es ist, würden Sie wahrscheinlich nicht in der Lage sein , dies überhaupt zu tun, ohne etwas hässlich wie alle stdin auf eine Variable zu erfassen und dann kochend oder <<<die Variable in dem ersten Umleitung venv/bin/activateund dann main.py.


Ein sehr offensichtliches Beispiel dafür, was hier passiert und warum dies funktioniert, ist das folgende sh-Skript kitten.sh:

#!/bin/sh
cat

Es wird nur ausgeführt cat, wobei von stdin aus gelesen und die Eingabe in stdout gedruckt wird.

cas
quelle
5
awww ... das Kätzchen ist so süß, es hat seine eigene Shebang-Linie.
Cas
HI @cas Danke für die ausführliche Antwort. Und ja, es funktioniert so, wie es sollte. Ich habe meine Frage erweitert, um zu verdeutlichen, in welchem ​​Kontext ich sie verwenden möchte und wo sie nicht funktioniert. Vielleicht ist diese SE dann das falsche Forum, um die Frage zu stellen.
Nanitous
Die Bearbeitung dauerte mehr als 6 Minuten ;-)
Nanitous
Wenn andere Befehle früher im Skript stdin verwenden müssen (zukünftige Änderungen am Skript usw.), verfügen einige Betriebssysteme über Pseudodateinamen, die als Platzhalter weitergegeben werden können. Unter vielen Linux- /dev/stdinVarianten befindet sich beispielsweise eine Gerätedatei (oder ein Symlink zu einer solchen), die beim Lesen das Richtige tut. Der Nachteil ist natürlich, dass die Portabilität auf die Betriebssysteme beschränkt ist, deren spezielle Namen Sie kennen, z. B. indem Sie dem entsprechenden gefälschten Dateinamen eine lokale Variable zuweisen und dann die Variable als Argument verwenden python main.py.
Ti Strga
Der gesamte Zweck des OP-Skripts besteht darin, die Umgebung für Python einzurichten und dann stdin an main.py zu übergeben. Alles, was dies getan hat, würde es beschädigen.
Cas