esta respuestaanaliza cómo ejecutar un fragmento de Python de varias líneas desde la línea de comando en una terminal. Noté que la respuesta funciona muy bien dentro de los scripts de Shell, incluso con sangría anidada, lo cual es muy bueno, por ejemplo
#!/bin/bash
some_text="Hello world"
echo $some_text
cat <<EOF | python -
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
huellas dactilares:
0
hello
hello
1
hello
hello
2
hello
hello
Sin embargo, me resulta difícil compartir variables entre el script de shell y el fragmento de Python.
¿Cómo puedo recopilar la salida del subíndice de Python en el script bash? (por ejemplo, en una variable como
$output
).¿Cómo puedo pasar una variable bash (por ejemplo
$some_text
) al script de Python?
Respuesta1
Obtener una variable para Python
Dado que (cuando el EOF
marcador no está entre comillas) la sustitución de variables se produce antes de que el texto pase del heredoc a python
la entrada estándar, puede incluir la variable directamente en el script.
python - <<EOF
some_text = "$some_text"
EOF
Si some_text
fuera así test
, Python lo vería some_text = "test"
. Sin embargo, tenga en cuenta que puede verse como una vulnerabilidad de inyección de código. Si some_text
fuera "; import os; os.system("evil-command"); x = "
, por ejemplo, Python vería:
some_text = ""; import os; os.system("evil-command"); x = ""
y ejecutar ese comando malvado.
Si desea poder incorporar su código Python directamente a un script sin modificaciones, puede exportar su variable.
export some_text
y utilizar os.environ
para recuperarlo.
some_text = os.environ['some_text']
Ese es un enfoque mucho más sensato y seguro.
Obtener resultados de Python
Puede utilizar la sustitución de comandos para recopilar la salida del script.
output=$(
python - <<EOF
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
)
(tenga en cuenta que se eliminan todos los caracteres de nueva línea finales)
Respuesta2
El problema con su enfoque es que el script Python incorporado ya no tiene acceso a la entrada estándar original (ya que su entrada estándar es... ella misma).
Si eso es un problema, puedes escribir:
python -c '
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
'
O si el script de Python puede contener comillas simples:
python -c "$(cat << 'EOF'
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
)"
O:
python <(cat << 'EOF'
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
)
Respuesta3
Utilice un guión como nombre de archivo:
ruby - a b <<'END'
puts ARGV.join(",")
END
python - a b <<'END'
import sys
print ",".join(sys.argv[1:])
END
No sé si sys.argv[1:]
es la forma correcta de hacer esto en Python. Para -e/-c puedes especificar el final de los argumentos con --:
set -- -a -b -c
ruby -e 'puts ARGV.join(",")' -- "$@"
python -c 'import sys; print ",".join(sys.argv[2:])' -- "$@"
Capturando resultados y redirigiendo STDERR:
x=$(ruby <<'END' 2> /dev/null
puts "a"
abort "b"
END
)
Respuesta4
1) Puede escribir asignaciones de variables a un archivo en Python y luego obtenerlo en su script bash.
2) Dado que su palabra (EOF) no está entre comillas, todas las líneas del documento aquí están sujetas a expansión de parámetros. Puedes usar esto para pasar cosas al script de Python.