Voglio passare lo stdin a uno script bash a uno script python chiamato in quello script bash


9

Ho uno script bash che invoca uno script Python di cui voglio alimentare il contenuto filetramite via stdin. Chiamando lo script bash come:

./script.sh < file

E i contenuti di script.sh:

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

Non ho idea di cosa compilare per ??????passare il contenuto di filedato allo script bash come stdin allo script python main.py.

Si noti che filepuò essere un file di testo sostanziale e l'utilizzo di bash nonread è auspicabile.

L'uso di stdin quando si richiama lo script bash è un requisito. Sono flessibile per passare qualunque cosa main.py.

Qualche idea là fuori su come affrontare questo enigma?

aggiunta

La risposta di @cas mi ha chiarito che ho anche bisogno di spiegare in quale contesto cerco di usare script.sh.

Voglio usare script.shcome script di inoltro in ~/.forward, con il contenuto:

|/path/to/script.sh

Quale postfisso chiama come /path/to/script.sh; il registro è chiaro al riguardo. Un semplice test che utilizza una versione ridotta dello script Python, come:

|/path/to/simple/main.py

Dimostra che postfix chiama main.pycon il contenuto della posta sullo stdin. Ma la combinazione non sembra funzionare.


stai usando la localLDA di Postfix o qualcos'altro, come procmailo deliver? c'è qualcosa nel tuo ~/.bashrcche potrebbe disturbare l'ambiente visto da main.pyquando viene eseguito dall'interno script.sh? forse registrare l'ambiente eseguendo qualcosa di simile { typeset -p ; echo } >> "/tmp/forward.log"all'interno di script.sh.
Cas

Risposte:


15

Supponendo che la tua main.pysceneggiatura sia scritta correttamente per essere letta da stdin e che nulla nelle venv/bin/activateletture di stdin (*), ??????dovrebbe essere "niente".

Non ci sono comandi precedenti nello script bash che consumeranno stdin prima di Python, quindi Python inizierà a consumarlo.

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

O rendere main.pyeseguibile ed eseguirlo direttamente come ./main.py... funziona allo stesso modo, in entrambi i modi.

(*) se ci fosse, probabilmente non saresti in grado di farlo affatto, senza qualcosa di brutto come catturare tutto lo stdin in una variabile e poi <<<reindirizzare o reindirizzare prima la variabile venv/bin/activatee poi main.py.


Per un esempio molto ovvio di ciò che sta accadendo qui e perché funziona, considera il seguente script sh kitten.sh:

#!/bin/sh
cat

Funziona appena cat, che inizia a leggere da stdin e stampa il suo input su stdout.


5
awww ... il gattino è così carino, ha una sua linea di shebang.
Cas

HI @cas Grazie per la risposta estesa. E sì, funziona come dovrebbe. Ho esteso la mia domanda per chiarire in quale contesto sto cercando di usarlo e dove non funziona. Potrebbe essere allora questo SE è il forum sbagliato per porre la domanda.
nanoso

La modifica mi ha richiesto più di 6 minuti ;-)
nanoso

Se altri comandi precedenti nello script devono consumare stdin (future modifiche allo script, eccetera), alcuni sistemi operativi hanno pseudo-nomi di file che possono essere passati come segnaposto. In molte versioni di Linux, ad esempio, /dev/stdinè presente un file del dispositivo (o un collegamento simbolico a tale) che farà la cosa giusta quando viene letto. Il compromesso, ovviamente, è che la portabilità è limitata ai sistemi operativi di cui conosci i nomi speciali, ad esempio, assegnando una variabile locale al nome file falso appropriato e quindi usando la variabile come argomento python main.py.
Ti Strga,

l'intero scopo dello script dell'OP è di configurare l'ambiente per Python e quindi passare lo stdin a main.py, quindi tutto ciò che lo farebbe lo spezzerebbe.
Caso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.