¿Cómo llamar a un script de shell desde código python?

211

¿Cómo llamar a un script de shell desde código python?

Umesh K
fuente

Respuestas:

252

El módulo de subproceso lo ayudará.

Ejemplo descaradamente trivial:

>>> import subprocess
>>> subprocess.call(['./test.sh']) # Thanks @Jim Dennis for suggesting the []
0 
>>> 

Donde test.shes un script de shell simple y 0es su valor de retorno para esta ejecución.

Manoj Govindan
fuente
11
Nota: es preferible pasar subprocess.call () una lista en lugar de una cadena (consulte el comando Hugo24 a continuación para ver el ejemplo y los motivos).
Jim Dennis
1
El enlace al tutorial está roto.
Kshitij Saraogi
66
Esto proporciona: OSError: [Errno 13] Permiso denegado. mi script no requiere ejecutarse con sudo. @Manoj Govindan
alper
66
Con argumentos: subprocess.call (['./ test.sh', 'param1', 'param2'])
Henry
2
@alper ir a la carpeta donde ha colocado la secuencia de comandos y ejecutar el comando, chmod +x script.sh. Nota: script.sh es un marcador de posición para su script, reemplácelo en consecuencia.
Tom J Muthirenthi
106

Hay algunas formas de usar os.popen()(en desuso) o todo el subprocessmódulo, pero este enfoque

import os
os.system(command)

Es uno de los más fáciles.

Michał Niklas
fuente
1
¿Por qué no es esta la respuesta más votada? ¿No es tener que importar un módulo la mejor solución? Debe haber algún inconveniente aquí?
boulder_ruby
66
Con subprocessusted puede administrar tuberías de entrada / salida / error. También es mejor cuando tiene muchos argumentos, os.command()ya que tendrá que crear una línea de comando completa con caracteres especiales de escape, con subprocessuna simple lista de argumentos. Pero para tareas simples os.command() puede ser suficiente.
Michał Niklas
1
Para citar de ese enlace:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
Maximiliano
42

En caso de que desee pasar algunos parámetros a su script de shell, puede usar el método shlex.split () :

import subprocess
import shlex
subprocess.call(shlex.split('./test.sh param1 param2'))

con test.shen la misma carpeta:

#!/bin/sh
echo $1
echo $2
exit 0

Salidas:

$ python test.py 
param1
param2
Franck Dernoncourt
fuente
Esto es elegante
caleb
20
import os
import sys

Suponiendo que test.sh es el script de shell que desea ejecutar

os.system("sh test.sh")
Srayan Guhathakurta
fuente
15

Utilice el módulo de subproceso como se mencionó anteriormente.

Lo uso así:

subprocess.call(["notepad"])
hugo24
fuente
13
Nota: llamar al subproceso con una lista es más seguro, ya que no necesita pasar la cadena (potencialmente no saneada) a través de un shell para su análisis / interpretación. El primer elemento de la lista será el ejecutable y todos los demás elementos se pasarán como argumentos.
Jim Dennis
13

Estoy ejecutando python 3.5 y subprocess.call (['./ test.sh']) no funciona para mí.

Te doy tres soluciones depende de lo que quieras hacer con la salida.

1 - guión de llamada. Verá la salida en su terminal. La salida es un número.

import subprocess 
output = subprocess.call(['test.sh'])

2 - ejecución de llamada y volcado y error en cadena. No ve la ejecución en su terminal a menos que imprima (stdout). Shell = Verdadero ya que el argumento en Popen no funciona para mí.

import subprocess
from subprocess import Popen, PIPE

session = subprocess.Popen(['test.sh'], stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()

if stderr:
    raise Exception("Error "+str(stderr))

3 - llama al script y volca los comandos echo de temp.txt en temp_file

import subprocess
temp_file = open("temp.txt",'w')
subprocess.call([executable], stdout=temp_file)
with open("temp.txt",'r') as file:
    output = file.read()
print(output)

No olvides echar un vistazo al subproceso de documentación

lauralacarra
fuente
1
Nota No utilice stdout = PIPE o stderr = PIPE con subprocess.call. El proceso secundario se bloqueará si genera suficiente salida a una tubería para llenar el búfer de tubería del sistema operativo ya que no se están leyendo las tuberías.
4

El módulo de subproceso es un buen módulo para iniciar subprocesos. Puede usarlo para llamar a comandos de shell como este:

subprocess.call(["ls","-l"]);
#basic syntax
#subprocess.call(args, *)

Puedes ver su documentación aquí.

Si tiene su script escrito en algún archivo .sh o en una cadena larga, puede usar el módulo os.system. Es bastante simple y fácil llamar:

import os
os.system("your command here")
# or
os.system('sh file.sh')

Este comando ejecutará el script una vez, hasta su finalización, y lo bloqueará hasta que salga.

Ankit Singh
fuente
¿No tienes que importar sys también?
ScottyBlades
No, tu no; intente abrir un shell de Python y ejecutar este fragmento
Descartes
4

En caso de que el script tenga múltiples argumentos

#!/usr/bin/python

import subprocess
output = subprocess.call(["./test.sh","xyz","1234"])
print output

La salida dará el código de estado. Si el script se ejecuta con éxito, dará 0, de lo contrario, un número entero distinto de cero

podname=xyz  serial=1234
0

A continuación se muestra el script de shell test.sh.

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"
Rishi Bansal
fuente
2

El subproceso es bueno, pero a algunas personas les puede gustar más la escritura . Scriptine tiene más conjunto de métodos de alto nivel como shell.call (args) , path.rename (new_name) y path.move (src, dst) . La escritura se basa en subprocesos y otros.

Dos inconvenientes de la escritura:

  • El nivel de documentación actual sería más completo aunque sea suficiente.
  • A diferencia del subproceso, el paquete de scriptine actualmente no está instalado por defecto.
Akseli Palén
fuente
2

Sé que esta es una pregunta antigua, pero me topé con esto recientemente y terminó por desviarme desde la API de subproceso , modificada desde Python 3.5.

La nueva forma de ejecutar scripts externos es con la runfunción, que ejecuta el comando descrito por args. Espera a que se complete el comando y luego devuelve una instancia de CompletedProcess.

import subprocess

subprocess.run(['./test.sh'])
Kévin Sanchez Lacroix
fuente
1

Si su archivo de script de shell no tiene permisos de ejecución, hágalo de la siguiente manera.

import subprocess
subprocess.run(['/bin/bash', './test.sh'])
thomasXu
fuente
-9

Por favor, intente los siguientes códigos:

Import Execute 

Execute("zbx_control.sh")
Manas
fuente