run - python execute shell script
incrustando secuencias cortas de python dentro de un script bash (9)
Me gustaría insertar el texto de las secuencias cortas de Python dentro de una secuencia de comandos bash, para usar en decir, mi .bash_profile
. ¿Cuál es la mejor manera de hacer tal cosa?
La solución que tengo hasta ahora es llamar al intérprete de Python con la opción -c
, y decirle al intérprete que exec
lo que lee de stdin
. A partir de ahí, puedo construir herramientas simples como las siguientes, lo que me permite procesar el texto para utilizarlo en mi aviso interactivo:
function pyexec() {
echo "$(/usr/bin/python -c ''import sys; exec sys.stdin.read()'')"
}
function traildirs() {
pyexec <<END
trail=int(''${1:-3}'')
import os
home = os.path.abspath(os.environ[''HOME''])
cwd = os.environ[''PWD'']
if cwd.startswith(home):
cwd = cwd.replace(home, ''~'', 1)
parts = cwd.split(''/'')
joined = os.path.join(*parts[-trail:])
if len(parts) <= trail and not joined.startswith(''~''):
joined = ''/''+joined
print joined
END
}
export PS1="/h [/$(traildirs 2)] % "
Sin embargo, este enfoque me suena un poco gracioso, y me pregunto qué alternativas podría haber para hacerlo de esta manera.
Mis habilidades de scripts bash son bastante rudimentarias, por lo que estoy particularmente interesado en saber si estoy haciendo algo tonto desde la perspectiva del intérprete bash.
¿Por qué debería necesitar usar -c
? Esto funciona para mí:
python << END
... code ...
END
sin necesidad de nada extra.
A veces no es una buena idea usar aquí el documento. Otra alternativa es usar python -c:
py_script="
import xml.etree.cElementTree as ET,sys
...
"
python -c "$py_script" arg1 arg2 ...
El intérprete de Python acepta -
en la línea de comandos como sinónimo de stdin
para que pueda reemplazar las llamadas a pyexec con:
python - <<END
Ver referencia de línea de comando here .
Interesante ... quiero una respuesta ahora también ;-)
Él no está preguntando cómo ejecutar código python dentro de un script bash, pero en realidad tiene las variables de entorno configuradas python.
Pon esto en un script bash e intenta que diga "funcionó".
export ASDF="it didn''t work"
python <<END
import os
os.environ[''ASDF''] = ''it worked''
END
echo $ASDF
El problema es que Python se ejecuta en una copia del entorno. Cualquier cambio en ese entorno no se ve después de las salidas de Python.
Si hay una solución para esto, me encantaría verlo también.
Listo para copiar y pegar el ejemplo con la entrada:
input="hello"
output=`python <<END
print "$input world";
END`
echo $output
Prueba esto :
#!/bin/bash
a="test"
python -c "print ''$a this is a test''.title()"
Si está usando zsh, puede incrustar Python dentro de la secuencia de comandos usando zsh''s join y python stdin option ( python -
):
py_cmd=${(j:/n:)"${(f)$(
# You can also add comments, as long as you balance quotes
<<<''if var == "quoted text":''
<<<'' print "great!"'')}"}
catch_output=$(echo $py_cmd | python -)
Puede sangrar el fragmento de Python, por lo que se ve mejor que las soluciones EOF
o <<END
cuando está dentro de las funciones.
Si necesita utilizar la salida de python en el script bash, puede hacer algo como esto:
#!/bin/bash
ASDF="it didn''t work"
ASDF=`python <<END
ASDF = ''it worked''
print ASDF
END`
echo $ASDF
Un problema con el uso del here document
bash here document
es que el script se pasa a Python en stdin
, por lo que si desea usar el script de Python como filtro, se vuelve difícil de manejar. Una alternativa es usar la process substitution
bash
, algo como esto:
... | python <( echo ''
code here
'' ) | ...
Si la secuencia de comandos es demasiado larga, también puede usar here document
dentro de la página, así:
... | python <(
cat << "END"
code here
END
) | ...
Dentro de la secuencia de comandos, puede leer / escribir como lo haría normalmente desde / hasta la sys.stdin.readlines
/ sys.stdin.readlines
estándar (por ejemplo, sys.stdin.readlines
para engullir toda la entrada).
Además, python -c
se puede usar como se menciona en otras respuestas, pero aquí es cómo me gusta hacerlo para formatear muy bien, respetando las reglas de sangrado ( credits ) de Python:
read -r -d '''' script <<-"EOF"
code goes here prefixed by hard tab
EOF
python -c $script
Solo asegúrese de que el primer carácter de cada línea dentro del documento aquí sea una pestaña difícil. Si tiene que poner esto dentro de una función, entonces utilizo el siguiente truco que vi en algún lugar para que se vea alineado:
function somefunc() {
read -r -d '''' script <<-"----EOF"
code goes here prefixed by hard tab
----EOF
python -c $script
}