Come chiamare uno script di shell dal codice Python?


211

Come chiamare uno script di shell dal codice Python?

Risposte:


252

Il modulo di sottoprocesso ti aiuterà.

Esempio palesemente banale:

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

Dov'è test.shun semplice script di shell ed 0è il suo valore di ritorno per questa corsa.


11
Nota: è preferibile passare a subprocess.call () un elenco piuttosto che una stringa (vedere l'esempio seguente per Hugo24 per motivi e motivi).
Jim Dennis,

1
Il collegamento al tutorial è interrotto.
Kshitij Saraogi,

6
Questo dà: OSError: [Errno 13] Autorizzazione negata. il mio script non deve essere eseguito con sudo. @Manoj Govindan
alper,

6
Con argomenti: subprocess.call (['./ test.sh', 'param1', 'param2'])
Henry,

2
@alper andare nella cartella dove avete posto lo script ed eseguire il comando, chmod +x script.sh. Nota: script.sh è un segnaposto per il tuo script, sostituiscilo di conseguenza.
Tom J Muthirenthi,

106

Ci sono alcuni modi usando os.popen()(deprecato) o l'intero subprocessmodulo, ma questo approccio

import os
os.system(command)

è uno dei più semplici.


1
perché questa non è la risposta più votata? Non è necessario importare un modulo la soluzione migliore? Deve esserci qualche inconveniente qui?
boulder_ruby,

6
Con subprocesspuoi gestire i tubi di input / output / error. È anche meglio quando hai molti argomenti - con os.command()te dovrai creare l'intera riga di comando con caratteri speciali di escape, con un subprocesssemplice elenco di argomenti. Ma per compiti semplici os.command() può essere sufficiente.
Michał Niklas

1
Per citare da quel link:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
Massimiliano

42

Nel caso in cui si desideri passare alcuni parametri allo script della shell, è possibile utilizzare il metodo shlex.split () :

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

con test.shnella stessa cartella:

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

Uscite:

$ python test.py 
param1
param2

Questo è elegante
caleb,

20
import os
import sys

Supponendo test.sh è lo script della shell che si desidera eseguire

os.system("sh test.sh")

15

Utilizzare il modulo di sottoprocesso come indicato sopra.

Lo uso così:

subprocess.call(["notepad"])

13
Nota: chiamare un sottoprocesso con un elenco è più sicuro poiché non richiede il passaggio della stringa (potenzialmente non autenticata) attraverso una shell per l'analisi / interpretazione. Il primo elemento nell'elenco sarà l'eseguibile e tutti gli altri elementi verranno passati come argomenti.
Jim Dennis,

13

Sto eseguendo python 3.5 e subprocess.call (['./ test.sh']) non funziona per me.

Ti do tre soluzioni dipende da cosa vuoi fare con l'output.

1 - chiama lo script. Vedrai un output nel tuo terminale. l'output è un numero.

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

2 - chiama ed esegue il dump dell'esecuzione e dell'errore nella stringa. Non vedi l'esecuzione nel tuo terminale a meno che non stampi (stdout). Shell = True come argomento in Popen non funziona per me.

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 - chiama lo script e scarica i comandi echo di temp.txt in 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)

Non dimenticare di dare un'occhiata al sottoprocesso del documento


1
Nota Non utilizzare stdout = PIPE o stderr = PIPE con subprocess.call. Il processo figlio si bloccherà se genera un output sufficiente per una pipe per riempire il buffer delle pipe del sistema operativo poiché le pipe non vengono lette.

4

Il modulo dei sottoprocessi è un buon modulo per avviare i sottoprocessi. Puoi usarlo per chiamare i comandi di shell come questo:

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

Puoi vedere la sua documentazione qui.

Se lo script è stato scritto in un file .sh o in una stringa lunga, è possibile utilizzare il modulo os.system. È abbastanza semplice e facile da chiamare:

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

Questo comando eseguirà lo script una volta, fino al completamento, e lo bloccherà fino alla sua uscita.


Non devi importare anche sys?
ScottyBlades,

No, non lo fai; prova ad aprire una shell Python ed eseguire questo frammento
Descartes,

4

Nel caso in cui lo script abbia più argomenti

#!/usr/bin/python

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

L'output fornirà il codice di stato. Se lo script viene eseguito correttamente, verrà restituito 0 intero diverso da zero.

podname=xyz  serial=1234
0

Di seguito è riportato lo script della shell test.sh.

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"

2

Il sottoprocesso è buono ma ad alcune persone potrebbe piacere di più la scriptina . Scriptine ha un set di metodi più di alto livello come shell.call (args) , path.rename (new_name) e path.move (src, dst) . La scriptina si basa su sottoprocessi e altri.

Due svantaggi della scriptine:

  • L'attuale livello di documentazione sarebbe più completo anche se è sufficiente.
  • A differenza del sottoprocesso, il pacchetto di scriptine non è attualmente installato per impostazione predefinita.

2

So che questa è una vecchia domanda, ma di recente mi sono imbattuto in questo e alla fine mi ha sbagliato a guidare l' API di sottoprocesso come modificata da Python 3.5.

Il nuovo modo di eseguire script esterni è con la runfunzione, che esegue il comando descritto da args. Attende il completamento del comando, quindi restituisce un'istanza CompletedProcess.

import subprocess

subprocess.run(['./test.sh'])

1

Se il file di script della shell non dispone delle autorizzazioni di esecuzione, procedere come segue.

import subprocess
subprocess.run(['/bin/bash', './test.sh'])

-9

Prova i seguenti codici:

Import Execute 

Execute("zbx_control.sh")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.