¿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?

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.


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.


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

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")

15

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

Lo uso así:

subprocess.call(["notepad"])

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


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.


¿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"


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'])

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'])

-9

Por favor, intente los siguientes códigos:

Import Execute 

Execute("zbx_control.sh")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.