Con iterpipes, python puede reemplacar a bash para scripting. En serio.
O al menos así era hasta que hoy me encontré con iterpipes en python.reddit.com
Iterpipes es "una biblioteca para usar pipelines de shell usando sintaxis parecida al shell" y ¿sabés qué? Es brillante.
Acá hay un ejemplo de su página de PYPI:
# Total lines in *.py files under /path/to/dir, # use safe shell parameters formatting: >>> total = cmd( ... 'find {} -name {} -print0 | xargs -0 wc -l | tail -1 | awk {}', ... '/path/to/dir', '\*.py', '{print $1}') >>> run(total | strip() | join | int) 315
Así sería en shell:
find /path/to/dir -name '*.py' -print0 | xargs -0 wc -l | tail -1 | awk '{print $1}'
Tal vez digas que la versión de shell es más sencilla. Eso es una ilusión causada por la densidad del campo malico del shell: esa versión tiene bugs.
Porqué tiene bugs? Porque si controlo qué hay adentro de /path/to/dir
puedo hacer que falle [1], pero en python puedo manejar el error.
También en la mayoría de los intentos de escribir ese comando sería inseguro porque las reglas de comillas y caracteres de escape de shell son dementes.
La versión de iterpipes usa el equivalente de prepared statements de SQL que debería ser más seguro.
Es casi imposible hacer ese comando en puro shell y estar seguro de que es seguro.
Además la versión en shell produce un string en vez de un entero, que es una bazofia si lo necesitás usar para algo.
Y el beneficio más importante es, por supuesto, no cuando tratás de hacer que python funcione como un shell, sino cuando podés dejar de hacer como que el shell es un lenguaje de verdad.
Comsideremos esta gema del script /etc/rc.shutdown
en Arch Linux. DAEMONS es una lista de cosas que se arrancaron al inicio, y este script intenta detenerlas en orden inverso, a menos que el nombre empiece con "!":
# Shutdown daemons in reverse order let i=${#DAEMONS[@]}-1 while [ $i -ge 0 ]; do if [ "${DAEMONS[$i]:0:1}" != '!' ]; then ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@} fi let i=i-1 done
¿No es lindo?
¿Y cómo se vería en python? (tal vez haya invertido el significado de ck_daemon):
# Shutdown daemons in reverse order for daemon in reversed(DAEMONS): if daemon[0]=='!': continue if ck_daemon(daemon): stop_daemon(daemon)
Mientras que stop_daemon solía ser esto:
stop_daemon() { /etc/rc.d/$1 stop }
Ahora será esto:
.. code-block:: python
- def stop_daemon(daemon):
run(cmd('/etc/rc.d/{} stop',daemon))
Vamos gente, estamos en pleno siglo 21, y el shell scripting ya era feo en el 20.