2010-11-23 24 views
8

Tengo un script bash, a.sh, y en él tengo un script python b.py. El script de python calcula algo, y quiero que devuelva un valor que se usará más adelante en a.sh. Sé que puedo hacerCómo pasar variables del script de Python al script bash

En a.sh:

var=`python b.py` 

En b.py:

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

pero esto no es tan conveniente, porque yo también imprimir otros mensajes en b. py

¿Hay alguna forma mejor de hacerlo?

Editar:

Lo que estoy haciendo ahora es sólo

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

Significa que puedo imprimir muchas cosas dentro b.py, pero sólo la última línea (el último comando de impresión, suponiendo que no contenga "\ n" en él) se almacenará en var.

¡Gracias por todas las respuestas!

+1

Bueno, tal vez no podrías hacer el script por lotes para empezar: haz todo desde Python, donde la diferencia entre los datos y el código es siempre clara, no tienes que generar un nuevo proceso simplemente para leer un valor escalar (como las respuestas que usan "cat" a continuación), y así sucesivamente. – jsbueno

Respuesta

7

Lo imprimiría en un archivo elegido en la línea de comando y luego obtendría ese valor en bash con algo como cat.

Así que iría:

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

[EDIT, otra idea en base a otras respuestas]

Su otra opción es dar formato a su salida con cuidado para que pueda utilizar las funciones de bash como head/tail para canalizar solo las primeras/últimas líneas en su próximo programa.

+0

Pegúenme a eso ;-) – Cameron

+0

:-) Aunque yo diría que no es feo en absoluto. Mantener la información en los archivos es exactamente para qué son los archivos. Permite una depuración mucho más fácil en una solución multiprograma a un problema. – Crisfole

+1

Quizás "feo" era demasiado fuerte ... Percibo que los archivos son más para el almacenamiento de datos a largo plazo. Escribir algo en un disco y luego leerlo milisegundos más tarde como medio para pasar datos en lo que conceptualmente un programa parece poco elegante para mí (¿para qué sirve RAM?). También hay alrededor de 10 mil millones de cosas que pueden salir mal al hacer E/S de archivos (aunque para ser justos, generalmente las cosas funcionan a la perfección). Por otro lado, ¡funciona! (Y las otras alternativas son aún menos sabrosas (o más complejas) - IPC en Bash, ¿alguien?) – Cameron

0

Puede escribir la salida en un archivo temporal y hacer que el shell lea y elimine ese archivo. Esto es aún menos conveniente, pero se reserva la extensión para la comunicación con el usuario.

Alternativamente, puede utilizar algún tipo de formato para stdout: las primeras n líneas son ciertas variables, el resto se repetirá por el shell principal para el usuario. También no es conveniente, pero evita el uso de archivos temporales.

1

No estoy seguro de "mejor", pero podría escribir el resultado en un archivo y luego volver a leerlo en Bash y eliminarlo después.

Esto es definitivamente feo, pero es algo a tener en cuenta en caso de que el truco no sea más importante.

1

En la secuencia de comandos Python, redirigir otros mensajes en stderr, e imprimir x a la salida estándar:

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

en la escritura del golpe:

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

Además, si x es un número entero entre 0255, puede utilizar código de salida para pasarlo a la fiesta:

import sys 
... 
sys.exit(x) 

en bash:

python b.py 
var=$? 

Tenga en cuenta que el código de salida se utiliza para indica errores, 0 significa que no hay error, y esto rompe la convención.

+0

Este fue mi otro pensamiento. Decidí que los archivos se sentían más "correctos" porque los otros mensajes no son todos "errores", basándome en lo que podía decir del OP. – Crisfole

3

Creo que la respuesta es

.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

El golpe backsticks works

que solemos hacer algo como

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


POWELINE_PATH=$PIP_PATH"/powerline" 
echo $POWELINE_PATH 
Cuestiones relacionadas