open - python execute shell script
¿Cómo implementar lenguajes bash comunes en Python? (17)
A partir de 2015 y el lanzamiento de Python 3.4, ahora hay una shell interactiva para usuarios razonablemente completa disponible en: http://xon.sh/ o https://github.com/scopatz/xonsh
El video de demostración no muestra las tuberías que se están utilizando, pero ESTÁN admitidas en el modo shell predeterminado.
Xonsh (''caracola'') trata muy duro de emular a bash, así que cosas para las que ya has ganado memoria muscular, como
env | uniq | sort -r | grep PATH
o
my-web-server 2>&1 | my-log-sorter
todavía funcionará bien.
El tutorial es bastante extenso y parece cubrir una cantidad significativa de la funcionalidad que alguien esperaría en general en un indicador de ash o bash:
- Compila, evalúa, y ejecuta!
- Historial de comandos y finalización de tabulación
- Ayuda y Superhelp con
?
&??
- Alias y solicitudes personalizadas
- Ejecuta comandos y / o scripts
*.xsh
que también se pueden importar - Variables de entorno incluyendo búsqueda con
${}
- Redirección de entrada / salida y combinación
- Antecedentes de trabajos y control de trabajo
- Anidado de subprocesos, tuberías y coprocesos
- Modo subproceso cuando existe un comando, modo Python de lo contrario
- Subproceso capturado con
$()
, Subproceso no capturado con$[]
, Evaluación de Python con@()
- Nombre de archivo Globbing con
*
o Expresión regular Nombre de archivo Globbing con Backticks
Actualmente hago mi manipulación de archivos de texto a través de un montón de AWK mal recordados, sed, Bash y un poco de Perl.
He visto algunos lugares donde Python es bueno para este tipo de cosas. ¿Cómo puedo usar Python para reemplazar los scripts de shell, AWK, sed y amigos?
Acabo de descubrir cómo combinar las mejores partes de bash y ipython. Hasta ahora esto me parece más cómodo que usar el subproceso, etc. Puede copiar fácilmente grandes partes de los scripts de bash existentes y, por ejemplo, agregar el manejo de errores en la forma de Python :) Y aquí está mi resultado:
#!/usr/bin/env ipython3
# *** How to have the most comfort scripting experience of your life ***
# ######################################################################
#
# … by using ipython for scripting combined with subcommands from bash!
#
# 1. echo "#!/usr/bin/env ipython3" > scriptname.ipy # creates new ipy-file
#
# 2. chmod +x scriptname.ipy # make in executable
#
# 3. starting with line 2, write normal python or do some of
# the ! magic of ipython, so that you can use unix commands
# within python and even assign their output to a variable via
# var = !cmd1 | cmd2 | cmd3 # enjoy ;)
#
# 4. run via ./scriptname.ipy - if it fails with recognizing % and !
# but parses raw python fine, please check again for the .ipy suffix
# ugly example, please go and find more in the wild
files = !ls *.* | grep "y"
for file in files:
!echo $file | grep "p"
# sorry for this nonsense example ;)
Consulte los documentos de IPython en los comandos de shell del sistema y cómo usarlos como shell del sistema .
Agregando a las respuestas anteriores: verifique el módulo pexpect para tratar con comandos interactivos (adduser, passwd, etc.)
Al principio había sh, sed y awk (y encontrar, y grep, y ...). Estuvo bien. Pero awk puede ser una pequeña bestia extraña y difícil de recordar si no la usas a menudo. Entonces el gran camello creó Perl. Perl era el sueño de un administrador de sistemas. Era como shell scripting en esteroides. El procesamiento de texto, incluidas las expresiones regulares, era solo una parte del lenguaje. Luego se puso feo ... La gente intentó hacer grandes aplicaciones con Perl. Ahora, no me malinterpretes, Perl puede ser una aplicación, pero puede (¡puede!) Parecer un desastre si no eres realmente cuidadoso. Luego está todo este negocio de datos planos. Es suficiente para conducir un programador loco.
Introduzca Python, Ruby, et al. Estos son realmente muy buenos lenguajes de propósito general. Admiten el procesamiento de texto y lo hacen bien (aunque quizás no tan estrechamente entrelazado en el núcleo básico del lenguaje). Pero también se escalan muy bien, y aún tienen un código bonito al final del día. También han desarrollado comunidades bastante fuertes con muchas bibliotecas para casi cualquier cosa.
Ahora, gran parte de la negatividad hacia Perl es una cuestión de opinión, y ciertamente algunas personas pueden escribir Perl muy limpias, pero con esta cantidad de personas quejándose de que es demasiado fácil crear código ofuscado, sabes que hay algo de verdad. La pregunta realmente se convierte entonces en si alguna vez va a utilizar este lenguaje para algo más que simples reemplazos de scripts de bash. Si no, aprende un poco más de Perl ... es absolutamente fantástico para eso. Si, por otro lado, quieres un lenguaje que crezca contigo a medida que quieras hacer más, ¿puedo sugerirte Python o Ruby?
De cualquier manera, ¡buena suerte!
Cualquier shell tiene varios conjuntos de características.
Los comandos esenciales de Linux / Unix. Todos estos están disponibles a través de la biblioteca de subprocess . Esta no es siempre la mejor primera opción para hacer todos los comandos externos. Busque también en shutil algunos comandos que son comandos de Linux separados, pero probablemente podría implementarlos directamente en sus scripts de Python. Otro enorme lote de comandos de Linux está en la biblioteca del sistema operativo; Puedes hacer esto más simplemente en Python.
Y - bonus! -- mas rapido. Cada comando de Linux separado en el shell (con algunas excepciones) ejecuta un subproceso. Al utilizar los módulos
shutil
yos
Python, no se bifurca un subproceso.Las características del entorno shell. Esto incluye cosas que establecen el entorno de un comando (directorio actual y variables de entorno y qué no). Puede administrar esto fácilmente desde Python directamente.
Las características de la programación de shell. Esta es toda la verificación del código de estado del proceso, los diversos comandos lógicos (si, mientras, para, etc.) el comando de prueba y todos sus parientes. La función de definición de cosas. Todo esto es mucho, mucho más fácil en Python. Esta es una de las grandes victorias para deshacerse de bash y hacerlo en Python.
Funciones de interacción. Esto incluye el historial de comandos y lo que no. No necesitas esto para escribir scripts de shell. Esto es solo para la interacción humana, y no para la escritura de guiones.
Las características de gestión de archivos de shell. Esto incluye la redirección y las tuberías. Esto es más complicado. Mucho de esto se puede hacer con subproceso. Pero algunas cosas que son fáciles en el shell son desagradables en Python. Específicamente cosas como
(a | b; c ) | something >result
(a | b; c ) | something >result
. Esto ejecuta dos procesos en paralelo (con salida dea
como entrada ab
), seguido de un tercer proceso. La salida de esa secuencia se ejecuta en paralelo consomething
y la salida se recopila en un archivo llamadoresult
. Eso es simplemente complejo de expresar en cualquier otro idioma.
Los programas específicos (awk, sed, grep, etc.) a menudo se pueden reescribir como módulos Python. No te vayas por la borda. Reemplaza lo que necesitas y evoluciona tu módulo "grep". No empieces a escribir un módulo de Python que reemplace "grep".
Lo mejor es que puedes hacer esto en pasos.
- Reemplace AWK y PERL con Python. Deja todo lo demás solo.
- Mira a reemplazar GREP con Python. Esto puede ser un poco más complejo, pero su versión de GREP puede adaptarse a sus necesidades de procesamiento.
- Mira a reemplazar FIND con bucles de Python que usan
os.walk
. Esta es una gran ganancia porque no genera tantos procesos. - Observe cómo reemplazar la lógica de shell común (bucles, decisiones, etc.) con scripts de Python.
Daré aquí mi opinión basada en la experiencia:
Para la concha:
- shell puede generar fácilmente código de sólo lectura. Escríbelo y cuando vuelva a él, nunca volverá a descubrir lo que hizo. Es muy fácil lograr esto.
- shell puede hacer MUCHO procesamiento de texto, división, etc. en una línea con tuberías.
- Es el mejor lenguaje de cola cuando se trata de integrar la llamada de programas en diferentes lenguajes de programación.
Para python:
- Si quieres portabilidad a las ventanas incluidas, usa Python.
- Python puede ser mejor cuando debes manipular algo más que texto, como las colecciones de números. Para esto, recomiendo python.
Por lo general, elijo bash para la mayoría de las cosas, pero cuando tengo algo que debe cruzar los límites de Windows, solo uso python.
He construido scripts de shell semi-largos (300-500 líneas) y código Python que hace una funcionalidad similar. Cuando se ejecutan muchos comandos externos, encuentro que el shell es más fácil de usar. Perl también es una buena opción cuando hay mucha manipulación de texto.
He publicado un paquete en PyPI: ez .
Use pip install ez
para instalarlo.
Ha empaquetado comandos comunes en shell y muy bien mi lib utiliza básicamente la misma sintaxis que shell. por ejemplo, cp (origen, destino) puede manejar archivos y carpetas! (Envoltura de shutil.copy shutil.copytree y decide cuándo usar cuál). Aún más agradable, puede soportar vectorización como R!
Otro ejemplo: no os.walk, use fls (ruta, expresión regular) para buscar archivos y filtrar recursivamente con expresiones regulares y devuelve una lista de archivos con o sin ruta completa
Ejemplo final: puedes combinarlos para escribir scripts muy simples:
files = fls(''.'',''py$''); cp(files, myDir)
Definitivamente echa un vistazo! ¡Me ha costado cientos de horas escribirlo / mejorarlo!
Mientras investigaba este tema, encontré este código de prueba de concepto (a través de un comentario en http://jlebar.com/2010/2/1/Replacing_Bash.html ) que le permite "escribir conductos tipo shell en Python usando una sintaxis concisa, y aprovechando las herramientas existentes del sistema donde tengan sentido ":
for line in sh("cat /tmp/junk2") | cut(d='','',f=1) | ''sort'' | uniq:
sys.stdout.write(line)
Puedes usar python en lugar de bash con la biblioteca github.com/lamerman/shellpy .
Aquí hay un ejemplo que descarga el avatar de un usuario de Python desde Github:
import json
import os
import tempfile
# get the api answer with curl
answer = `curl https://api.github.com/users/python
# syntactic sugar for checking returncode of executed process for zero
if answer:
answer_json = json.loads(answer.stdout)
avatar_url = answer_json[''avatar_url'']
destination = os.path.join(tempfile.gettempdir(), ''python.png'')
# execute curl once again, this time to get the image
result = `curl {avatar_url} > {destination}
if result:
# if there were no problems show the file
p`ls -l {destination}
else:
print(''Failed to download avatar'')
print(''Avatar downloaded'')
else:
print(''Failed to access github api'')
Como puede ver, todas las expresiones dentro del símbolo de acento grave (`) se ejecutan en shell. Y en el código Python, puede capturar los resultados de esta ejecución y realizar acciones en él. Por ejemplo:
log = `git log --pretty=oneline --grep=''Create''
Esta línea ejecutará primero git log --pretty=oneline --grep=''Create''
en shell y luego asignará el resultado a la variable de registro. El resultado tiene las siguientes propiedades:
stdout todo el texto de stdout del proceso ejecutado
stderr todo el texto desde stderr del proceso ejecutado
código de retorno código de retorno de la ejecución
Esta es una descripción general de la biblioteca, github.com/lamerman/shellpy se puede encontrar una descripción más detallada con ejemplos.
Sí, por supuesto :)
Eche un vistazo a estas bibliotecas que le ayudan a Nunca volver a escribir shell scripts (el lema de Plumbum).
Además, si desea reemplazar awk, sed y grep con algo basado en Python, le recomiendo pyp -
"Pyed Piper", o pyp, es una herramienta de manipulación de texto de línea de comandos de Linux similar a awk o sed, pero que utiliza métodos estándar de cadenas y listas de python, así como funciones personalizadas desarrolladas para generar resultados rápidos en un entorno de producción intenso.
Si la manipulación de su archivo de texto generalmente es de una sola vez, posiblemente se realice en el shell-prompt, no obtendrá nada mejor de python.
Por otro lado, si normalmente tiene que hacer la misma tarea (o similar) una y otra vez, y tiene que escribir sus scripts para hacerlo, entonces Python es genial, y puede crear fácilmente sus propias bibliotecas (puede hacerlo eso con shell scripts también, pero es más engorroso).
Un ejemplo muy simple para tener una sensación.
import popen2
stdout_text, stdin_text=popen2.popen2("your-shell-command-here")
for line in stdout_text:
if line.startswith("#"):
pass
else
jobID=int(line.split(",")[0].split()[1].lstrip("<").rstrip(">"))
# do something with jobID
Verifique también el módulo sys y getopt, son los primeros que necesitará.
Su mejor apuesta es una herramienta que está específicamente orientada a su problema. Si se trata de archivos de texto, Sed, Awk y Perl son los principales contendientes. Python es un lenguaje dinámico de propósito general. Al igual que con cualquier lenguaje de propósito general, hay soporte para la manipulación de archivos, pero ese no es el propósito principal. Consideraría Python o Ruby si tuviera un requisito para un lenguaje dinámico en particular.
En resumen, aprenda Sed y Awk realmente bien, además de todas las otras golosinas que vienen con su sabor de * nix (Todas las incorporaciones de Bash, grep, tr, etc.). Si lo que le interesa es el procesamiento de archivos de texto, ya está usando las cosas correctas.
Sugiero el impresionante libro en línea Dive Into Python . Es como aprendí el idioma originalmente.
Más allá de enseñarle la estructura básica del lenguaje y una gran cantidad de estructuras de datos útiles, tiene un buen capítulo sobre manejo de archivos y capítulos subsiguientes sobre expresiones regulares y más.
Una de las razones por las que amo Python es que está mucho mejor estandarizado que las herramientas POSIX. Tengo que verificar dos y tres veces que cada bit sea compatible con otros sistemas operativos. Un programa escrito en un sistema Linux podría no funcionar igual en un sistema BSD de OSX. Con Python, solo tengo que comprobar que el sistema de destino tenga una versión suficientemente moderna de Python.
Aún mejor, ¡un programa escrito en Python estándar incluso se ejecutará en Windows!
pythonpy es una herramienta que proporciona acceso fácil a muchas de las funciones de awk y sed, pero usando la sintaxis de python:
$ echo me2 | py -x ''re.sub("me", "you", x)''
you2
- Si desea usar Python como shell, ¿por qué no echa un vistazo a IPython ? También es bueno aprender interactivamente el idioma.
- Si haces mucha manipulación de texto, y si usas Vim como editor de texto, también puedes escribir directamente plugins para Vim en python. simplemente escriba ": help python" en Vim y siga las instrucciones o eche un vistazo a esta presentation . ¡Es tan fácil y poderoso escribir funciones que usarás directamente en tu editor!