2010-11-23 16 views
8

Ich habe ein Bash-Skript, a.sh, und darin habe ich ein Python-Skript b.py aufgerufen. Das Python-Skript berechnet etwas, und ich möchte, dass es einen Wert zurückgibt, der später in a.sh verwendet wird. Ich weiß, ichWie man Variablen vom Python-Skript zum Bash-Skript übergibt

tun kann

In a.sh:

var=`python b.py` 

In b.py:

print x # when x is the value I want to pass 

Aber das ist nicht so praktisch, weil ich in b andere Nachrichten auch drucken. py

Gibt es einen besseren Weg, es zu tun?

Edit:

Was ich jetzt tue ist nur

var=`python b.py | tail -n 1` 

Es bedeutet, dass ich viele Dinge in b.py drucken können, aber nur die letzte Zeile (die letzte Druckbefehl, vorausgesetzt, dass es "\ n" nicht enthält, wird in var gespeichert.

Danke für alle Antworten!

+1

Nun, vielleicht könntest du das Batch-Skript nicht starten - mach alles von Python, wo die Verteilung zwischen Daten und Code immer klar ist, du musst keinen neuen Prozess erzeugen, nur um einen Skalarwert zu lesen (wie die Antworten mit "Katze" unten), und so weiter. – jsbueno

Antwort

7

Ich würde es in eine Datei in der Befehlszeile ausgewählt dann würde ich diesen Wert in Bash mit etwas wie cat bekommen.

So würden Sie gehen:

python b.py tempfile.txt 
var=`cat tempfile.txt` 
rm tempfile.txt 

[EDIT, eine andere Idee auf andere Antworten basieren]

Die andere Option ist die Ausgabe sorgfältig zu formatieren, so dass Sie bash Funktionen wie head verwenden können/tail, um nur die ersten/letzten Zeilen in Ihr nächstes Programm zu leiten.

+0

Beat mich dazu ;-) – Cameron

+0

:-) Obwohl ich behaupten würde, es ist überhaupt nicht hässlich. Informationen in Dateien zu halten ist genau das, wofür Dateien sind. Es ermöglicht viel einfacheres Debuggen in einer Multiprogrammlösung für ein Problem. – Crisfole

+1

Vielleicht war "hässlich" zu stark ... ich empfinde Dateien eher als Langzeitspeicher für Daten. Etwas auf die Festplatte zu schreiben und es dann Millisekunden später als Mittel zu lesen, um Daten in einem konzeptionell einzelnen Programm herumzuleiten, erscheint mir unelegant (sicherlich ist das, wofür RAM ist?). Es gibt auch ungefähr 10 Milliarden Dinge, die bei Datei-I/O schiefgehen können (obwohl fair zu sein, funktioniert normalerweise alles perfekt). Auf der anderen Seite funktioniert es! (Und die anderen Alternativen sind noch weniger schmackhaft (oder komplexer) - IPC in Bash, jemand?) – Cameron

0

Sie können die Ausgabe in eine temporäre Datei schreiben und die Shell diese Datei lesen und löschen lassen. Dies ist noch weniger bequem, aber reserviert für die Kommunikation mit dem Benutzer.

Alternativ können Sie eine Art von Format für stdout verwenden: die ersten n Zeilen sind bestimmte Variablen, der Rest wird von der übergeordneten Shell an den Benutzer zurückgegeben. Auch nicht praktisch, aber vermeidet die Verwendung von Tempdateien.

1

Ich bin mir nicht sicher über "besser", aber Sie könnte schreiben Sie das Ergebnis in eine Datei dann lesen Sie es wieder in Bash und löschen Sie es danach.

Dies ist definitiv hässlich, aber es ist etwas zu beachten, falls nichts anderes den Trick macht.

1

In Ihrem Python-Skript, umleiten weitere Meldungen an stderr und x zu stdout drucken:

import sys 
... 
print >>sys.stderr, "another message" 
print x 

in dem Bash-Skript:

... 
var=`python b.py 2>/dev/null` 

Auch, wenn x eine ganze Zahl zwischen 0255,

import sys 
... 
sys.exit(x) 

in bash: Sie können Exit-Code zu übergeben es an der bash verwenden

Bitte beachten Sie, dass Exit-Code verwendet wird, um Fehler anzuzeigen, 0 bedeutet keinen Fehler, und dies bricht die Konvention.

+0

Das war mein anderer Gedanke. Ich entschied, dass sich die Dateien "korrekter" fühlten, weil die anderen Nachrichten nicht alle "Fehler" waren - genug, basierend auf dem, was ich vom OP sagen konnte. – Crisfole

3

Ich glaube, die Antwort ist

Py

import sys 
a=['zero','one','two','three'] 
b = int(sys.argv[1]) 
###your python script can still print to stderr if it likes to 
print >> sys.stderr, "I am no converting" 
result = a[b] 
print result 

.sh

#!/bin/sh 

num=2 
text=`python numtotext.py $num` 
echo "$num as text is $text" 
1

Auf bash backsticks works

ich usualy so etwas wie

PIP_PATH=`python -c "from distutils.sysconfig \ 
import get_python_lib; print(get_python_lib())"` 


POWELINE_PATH=$PIP_PATH"/powerline" 
echo $POWELINE_PATH 
Verwandte Themen