Jak wywołać skrypt powłoki z kodu python?

210

Jak wywołać skrypt powłoki z kodu python?

Umesh K
źródło

Odpowiedzi:

252

Podproces moduł będzie pomóc.

Rażąco trywialny przykład:

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

Gdzie test.shjest prosty skrypt powłoki i 0jego wartość zwracana dla tego uruchomienia.

Manoj Govindan
źródło
11
Uwaga: lepiej jest przekazać subprocess.call () listę niż ciąg znaków (patrz przykład dla Hugo24 poniżej, aby zapoznać się z przykładem i przyczynami).
Jim Dennis,
1
Link do samouczka jest uszkodzony.
Kshitij Saraogi
6
Daje to: OSError: [Errno 13] Odmowa dostępu. mój skrypt nie musi działać z sudo. @Manoj Govindan
alper
6
Z argumentami: subprocess.call (['./ test.sh', 'param1', 'param2'])
Henry
2
@alper przejdź do folderu w którym został umieszczony skrypt i uruchom polecenie chmod +x script.sh. Uwaga: skrypt.sh jest symbolem zastępczym skryptu, zamień go odpowiednio.
Tom J Muthirenthi
105

Istnieje kilka sposobów korzystania z os.popen()(przestarzałych) lub całego subprocessmodułu, ale takie podejście

import os
os.system(command)

jest jednym z najłatwiejszych.

Michał Niklas
źródło
1
dlaczego nie jest to najbardziej pozytywna odpowiedź? Czy nie trzeba importować modułu, co jest lepszym rozwiązaniem? To musi być jakaś wada?
boulder_ruby
6
Za pomocą subprocessmożesz zarządzać rurami wejścia / wyjścia / błędów. Jest to również lepsze, gdy masz wiele argumentów - os.command()będziesz musiał utworzyć całą linię poleceń ze znakami specjalnymi, z subprocessprostą listą argumentów. Ale dla prostych zadań os.command() może być po prostu wystarczające.
Michał Niklas
1
Cytat z tego linku:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
Maximilian
42

Jeśli chcesz przekazać pewne parametry do skryptu powłoki, możesz użyć metody shlex.split () :

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

zw test.shtym samym folderze:

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

Wyjścia:

$ python test.py 
param1
param2
Franck Dernoncourt
źródło
To jest eleganckie.
caleb
20
import os
import sys

Zakładając, że test.sh to skrypt powłoki, który chciałbyś wykonać

os.system("sh test.sh")
Srayan Guhathakurta
źródło
15

Użyj modułu podprocesu, jak wspomniano powyżej.

Używam tego w ten sposób:

subprocess.call(["notepad"])
hugo24
źródło
13
Uwaga: wywołanie podprocesu z listą jest bezpieczniejsze, ponieważ nie wymaga przepuszczania (potencjalnie niezarządzanego) ciągu przez powłokę w celu parsowania / interpretacji. Pierwszym elementem na liście będzie plik wykonywalny, a wszystkie pozostałe elementy zostaną przekazane jako argumenty.
Jim Dennis
13

Korzystam z języka Python 3.5 i subprocess.call (['./ test.sh']) nie działa dla mnie.

Daję ci trzy rozwiązania, w zależności od tego, co chcesz zrobić z produktem.

1 - skrypt wywołania. Zobaczysz wyjście w swoim terminalu. wyjście jest liczbą.

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

2 - wywołanie i zrzut zrzutu oraz błąd w łańcuch. Nie zobaczysz wykonania w swoim terminalu, dopóki nie wydrukujesz (standardowe wyjście). Shell = Prawda, ponieważ argument w Popen nie działa dla mnie.

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 - wywołaj skrypt i zrzuć polecenia echa temp.txt w pliku 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)

Nie zapomnij rzucić okiem na podproces dokumentu

lauralacarra
źródło
1
Uwaga Nie używaj stdout = PIPE lub stderr = PIPE z subprocess.call. Proces potomny zostanie zablokowany, jeśli wygeneruje wystarczającą moc wyjściową do potoku, aby wypełnić bufor potoku systemu operacyjnego, ponieważ rury nie są odczytywane.
4

Moduł podprocesu jest dobrym modułem do uruchamiania podprocesów. Możesz go użyć do wywoływania poleceń powłoki w następujący sposób:

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

Możesz zobaczyć jego dokumentację tutaj.

Jeśli masz skrypt napisany w pliku .sh lub długim ciągu, możesz użyć modułu os.system. Jest to dość proste i łatwe do wywołania:

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

To polecenie uruchomi skrypt raz, do końca, i zablokuje, dopóki nie zakończy działania.

Ankit Singh
źródło
Nie musisz też importować sys?
ScottyBlades,
Nie, ty nie; spróbuj otworzyć powłokę Pythona i uruchomić ten fragment kodu
Kartezjusza
4

W przypadku, gdy skrypt ma wiele argumentów

#!/usr/bin/python

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

Dane wyjściowe podadzą kod statusu. Jeśli skrypt uruchomi się pomyślnie, da 0 w przeciwnym razie liczbę całkowitą niezerową.

podname=xyz  serial=1234
0

Poniżej znajduje się skrypt powłoki test.sh.

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"
Rishi Bansal
źródło
2

Podproces jest dobry, ale niektórzy ludzie mogą bardziej lubić skrypty . Skrypty mają więcej zestawów metod wysokiego poziomu, takich jak shell.call (args) , path.rename (nowa_nazwa) i path.move (src, dst) . Skrypty oparte są na podprocesie i innych.

Dwie wady skryptu:

  • Obecny poziom dokumentacji byłby bardziej kompleksowy, nawet jeśli jest wystarczający.
  • W przeciwieństwie do podprocesu, pakiet skryptów nie jest obecnie domyślnie instalowany.
Akseli Palén
źródło
2

Wiem, że jest to stara sprawa, ale natknąłem się niedawno i skończyło się misguiding mnie od podproces API jak zmieniło od Pythona 3.5.

Nowym sposobem wykonywania zewnętrznych skryptów jest runfunkcja, która uruchamia polecenie opisane przez args. Czeka na wykonanie polecenia, a następnie zwraca instancję CompletedProcess.

import subprocess

subprocess.run(['./test.sh'])
Kévin Sanchez Lacroix
źródło
1

Jeśli plik skryptu powłoki nie ma uprawnień do wykonywania, zrób to w następujący sposób.

import subprocess
subprocess.run(['/bin/bash', './test.sh'])
thomasXu
źródło
-9

Wypróbuj następujące kody:

Import Execute 

Execute("zbx_control.sh")
Manas
źródło