Uruchamianie polecenia powłoki i przechwytywanie wyjścia
Chcę napisać funkcję, która wykona polecenie powłoki i zwróci jej wyjście jako łańcuch , bez względu na to, czy jest to Komunikat o błędzie czy sukcesie. Chcę tylko uzyskać taki sam wynik, jaki uzyskałbym za pomocą wiersza poleceń.
Jaki byłby przykład kodu, który zrobiłby coś takiego?
Na przykład:
def run_command(cmd):
# ??????
print run_command('mysqladmin create test -uroot -pmysqladmin12')
# Should output something like:
# mysqladmin: CREATE DATABASE failed; error: 'Can't create database 'test'; database exists'
18 answers
We wszystkich oficjalnie utrzymywanych wersjach Pythona, najprostszym podejściem jest użycie subprocess.check_output
funkcja:
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
check_output
uruchamia pojedynczy program, który pobiera tylko argumenty jako dane wejściowe.1 zwraca wynik dokładnie tak, jak Wydrukowano do stdout
. Jeśli chcesz zapisać dane wejściowe do stdin
, przejdź do sekcji run
lub Popen
. Jeśli chcesz wykonać złożone polecenia powłoki, zobacz notatkę shell=True
na końcu tej odpowiedzi.
Funkcja check_output
działa we wszystkich oficjalnie utrzymywane wersje Pythona. Jednak w przypadku nowszych wersji dostępne jest bardziej elastyczne podejście.
run
Jeśli używasz Pythona 3.5+ I nie potrzebujesz kompatybilności wstecznej, nowa funkcja run
jest zalecana przez oficjalną dokumentację dla większości zadań. Zapewnia bardzo ogólne, wysokiego poziomu API dla modułu subprocess
. Aby przechwycić wyjście programu, przekaż subprocess.PIPE
Flaga do argumentu słowa kluczowego stdout
. Następnie uzyskaj dostęp do atrybutu stdout
zwracanego CompletedProcess
obiekt:
>>> import subprocess
>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Wartość zwracana jest obiektem bytes
, więc jeśli chcesz mieć odpowiedni ciąg znaków, musisz go decode
. Przy założeniu, że wywołany proces zwróci kodowany w UTF-8 ciąg znaków:
>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
To wszystko może być skompresowane do jednej liniowej w razie potrzeby:
>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Jeśli chcesz przekazać dane wejściowe do stdin
procesu, możesz przekazać obiekt bytes
do słowa kluczowego input
argument:
>>> cmd = ['awk', 'length($0) > 5']
>>> ip = 'foo\nfoofoo\n'.encode('utf-8')
>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=ip)
>>> result.stdout.decode('utf-8')
'foofoo\n'
Możesz przechwytywać błędy, przekazując stderr=subprocess.PIPE
(przechwytywanie do result.stderr
) lub stderr=subprocess.STDOUT
(przechwytywanie do result.stdout
wraz ze zwykłym wyjściem). Jeśli chcesz run
wyrzucić wyjątek, gdy proces zwróci niezerowy kod zakończenia, możesz przekazać check=True
. (Lub możesz sprawdzić returncode
atrybut result
powyżej.) Gdy bezpieczeństwo nie jest problemem, można również uruchomić bardziej złożone polecenia powłoki, przekazując shell=True
, jak opisano na końcu tej odpowiedzi.
Późniejsze wersje Pythona usprawniają wyżej. W Pythonie 3.7+ powyższa jednowierszowa może być zapisana w następujący sposób:
>>> subprocess.run(['ls', '-l'], capture_output=True, text=True).stdout
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Użycie run
w ten sposób dodaje tylko trochę złożoności, w porównaniu do starego sposobu robienia rzeczy. Ale teraz możesz zrobić prawie wszystko, co musisz zrobić za pomocą samej funkcji run
.
Starsze wersje Pythona (3-3.4): więcej o check_output
Jeśli używasz starszej wersji Pythona lub potrzebujesz skromnej kompatybilności wstecznej, możesz użyć funkcji check_output
, Jak krótko opisano powyżej. Informatyka jest dostępny od wersji Python 2.7.
subprocess.check_output(*popenargs, **kwargs)
Pobiera te same argumenty co Popen
(patrz niżej) i zwraca łańcuch zawierający wyjście programu. Początek tej odpowiedzi zawiera bardziej szczegółowy przykład użycia. W Pythonie 3.5+, check_output
jest równoznaczne z wykonaniem run
z check=True
i stdout=PIPE
i zwróceniem tylko atrybutu stdout
.
Możesz przekazać stderr=subprocess.STDOUT
, aby upewnić się, że komunikaty o błędach są zawarte w zwracanym wyjściu. Gdy bezpieczeństwo nie jest problemem, można również Uruchom bardziej złożone polecenia powłoki, przekazując shell=True
, jak opisano na końcu tej odpowiedzi.
Jeśli chcesz przesyłać dane z stderr
lub przekazać dane wejściowe procesowi, check_output
nie będzie gotowe do zadania. Zobacz przykłady Popen
poniżej w tym przypadku.
Popen
Jeśli potrzebujesz głębokiej kompatybilności wstecznej lub jeśli potrzebujesz bardziej wyrafinowanej funkcjonalności niż check_output
lub run
, będziesz musiał pracować bezpośrednio z Popen
obiekty, które zawierają niskopoziomowe API dla podprocesów.
Konstruktor Popen
akceptuje albo pojedyncze polecenie bez argumentów, albo listę zawierającą polecenie jako pierwszą pozycję, po której następuje dowolna liczba argumentów, każdy jako oddzielny element listy. shlex.split
może pomóc w parsowaniu łańcuchów do odpowiednio sformatowanych list. Popen
obiekty akceptują również host różnych argumentów do zarządzania procesami i niskopoziomowymi konfiguracja.
Aby wysyłać dane wejściowe i przechwytywać dane wyjściowe, communicate
jest prawie zawsze preferowaną metodą. Jak w:
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
Lub
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
Jeśli ustawisz stdin=PIPE
, communicate
pozwala również na przekazywanie danych do procesu poprzez stdin
:
>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo\nfoofoo\n')
>>> print out
foofoo
Uwaga odpowiedź Aarona Halla , która wskazuje, że w niektórych systemach może być konieczne ustawienie stdout
, stderr
, i stdin
wszystkie do PIPE
(lub DEVNULL
), aby communicate
w ogóle zadziałały.
W niektórych rzadkich przypadkach, może być konieczne złożone, w czasie rzeczywistym przechwytywanie danych wyjściowych. odpowiedź Vartec sugeruje drogę naprzód, ale metody inne niż communicate
są podatne na blokady, jeśli nie są używane ostrożnie.
Podobnie jak w przypadku wszystkich powyższych funkcji, gdy bezpieczeństwo nie jest problemem, można uruchomić bardziej złożone polecenia powłoki przekazując shell=True
.
Uwagi
1. Uruchamianie poleceń powłoki: argument shell=True
Normalnie każde wywołanie do run
, check_output
, lub konstruktor Popen
wykonuje pojedynczy program . Że czyli żadnych fajek w stylu bash. Jeśli chcesz uruchomić złożone polecenia powłoki, możesz przekazać shell=True
, które obsługują wszystkie trzy funkcje. Na przykład:
>>> subprocess.check_output('cat books/* | wc', shell=True, text=True)
' 1299377 17005208 101299376\n'
Jednak robienie tego rodzi obawy o bezpieczeństwo. Jeśli robisz coś więcej niż lekkie Skrypty, możesz lepiej wywołać każdy proces osobno i przekazać dane wyjściowe z każdego jako wejście do następnego, za pomocą
run(cmd, [stdout=etc...], input=other_output)
Lub
Popen(cmd, [stdout=etc...]).communicate(other_output)
[81]}pokusa bezpośredniego łączenia rur jest silna; oprzyj się jej. W przeciwnym razie prawdopodobnie zobaczysz impasy lub będziesz musiał robić trudne rzeczy, takie jak to .Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-03 15:03:11
Jest to o wiele łatwiejsze, ale działa tylko na Uniksie (w tym Cygwin) i Python2.7.
import commands
print commands.getstatusoutput('wc -l file')
Zwraca krotkę z (return_value, output).
Dla rozwiązania, które działa zarówno w Python2 jak i Python3, użyj zamiast tego modułu subprocess
:
from subprocess import Popen, PIPE
output = Popen(["date"],stdout=PIPE)
response = output.communicate()
print response
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-12 16:36:40
Coś w tym stylu:
def runProcess(exe):
p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while(True):
# returns None while subprocess is running
retcode = p.poll()
line = p.stdout.readline()
yield line
if retcode is not None:
break
Zauważ, że Przekierowuję stderr na stdout, może to nie jest dokładnie to, czego chcesz, ale chcę również komunikaty o błędach.
Ta funkcja generuje linię po linii, gdy przychodzą (normalnie musiałbyś poczekać na zakończenie podprocesu, aby uzyskać wyjście jako całość).
W Twoim przypadku użycie byłoby:
for line in runProcess('mysqladmin create test -uroot -pmysqladmin12'.split()):
print line,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-28 10:30:33
Odpowiedź Varteca nie odczytuje wszystkich linijek, więc zrobiłem wersję, która zrobiła:
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
Użycie jest takie samo jak zaakceptowana odpowiedź:
command = 'mysqladmin create test -uroot -pmysqladmin12'.split()
for line in run_command(command):
print(line)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:24
To jest trudne ale super proste rozwiązanie, które sprawdza się w wielu sytuacjach:
import os
os.system('sample_cmd > tmp')
print open('tmp', 'r').read()
Plik tymczasowy (tutaj jest tmp) jest tworzony z wyjściem polecenia i można z niego odczytać żądane wyjście.
Extra notka z komentarzy: Plik tmp można usunąć w przypadku zadania jednorazowego. Jeśli musisz to zrobić kilka razy, nie ma potrzeby usuwania tmp.
os.remove('tmp')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-27 07:19:52
Miałem ten sam problem, ale wymyśliłem bardzo prosty sposób na zrobienie tego:
import subprocess
output = subprocess.getoutput("ls -l")
print(output)
Hope it helps out
Uwaga: To rozwiązanie jest specyficzne dla Python3, ponieważ subprocess.getoutput()
nie działa w Python2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-12 14:42:12
Możesz użyć następujących poleceń do uruchomienia dowolnego polecenia powłoki. Używałem ich na ubuntu.
import os
os.popen('your command here').read()
Uwaga: jest to przestarzałe od wersji Pythona 2.6. Teraz musisz użyć subprocess.Popen
. Poniżej znajduje się przykład
import subprocess
p = subprocess.Popen("Your command", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
print p.split("\n")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-18 05:41:10
Twój przebieg może się różnić, próbowałem spin @ senderle na rozwiązaniu Vartec w Windows na Pythonie 2.6.5, ale dostawałem błędy, i żadne inne rozwiązania nie działały. Mój błąd to: WindowsError: [Error 6] The handle is invalid
.
Odkryłem, że musiałem przypisać PIPE do każdego uchwytu, aby zwrócił oczekiwane wyjście - poniższe zadziałało dla mnie.
import subprocess
def run_command(cmd):
"""given shell command, returns communication tuple of stdout and stderr"""
return subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE).communicate()
I wywołanie w ten sposób, ([0]
otrzymuje pierwszy element krotki, stdout
):
run_command('tracert 11.1.0.1')[0]
Po dowiedzeniu się więcej, uważam, że potrzebuję tych argumentów, ponieważ Pracuję nad niestandardowym systemem, który używa różnych uchwytów, więc musiałem bezpośrednio kontrolować wszystkie choroby weneryczne.]}
Aby zatrzymać wyskakujące okienka konsoli (w systemie Windows), wykonaj następujące czynności:
def run_command(cmd):
"""given shell command, returns communication tuple of stdout and stderr"""
# instantiate a startupinfo obj:
startupinfo = subprocess.STARTUPINFO()
# set the use show window flag, might make conditional on being in Windows:
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
# pass as the startupinfo keyword argument:
return subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
startupinfo=startupinfo).communicate()
run_command('tracert 11.1.0.1')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-07 15:21:14
Miałem nieco inny smak tego samego problemu z następującymi wymaganiami:
- przechwytywanie i zwracanie wiadomości STDOUT, gdy gromadzą się one w buforze STDOUT (np. w czasie rzeczywistym).
-
@vartec rozwiązał ten problem używając generatorów i "wydajności"
słowo kluczowe powyżej
-
@vartec rozwiązał ten problem używając generatorów i "wydajności"
- wypisuje wszystkie linie Wyjścia ( nawet jeśli proces zakończy działanie przed buforem wyjścia może być w pełni odczytany ) Nie marnuj cykli procesora badanie procesu przy wysokiej częstotliwości
- Sprawdź kod powrotu podprocesu
- Print STDERR (oddzielony od STDOUT) jeśli otrzymamy niezerowy kod zwracający błąd.
Połączyłem i poprawiłem poprzednie odpowiedzi, aby uzyskać następujące odpowiedzi:
import subprocess
from time import sleep
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
# Read stdout from subprocess until the buffer is empty !
for line in iter(p.stdout.readline, b''):
if line: # Don't print blank lines
yield line
# This ensures the process has completed, AND sets the 'returncode' attr
while p.poll() is None:
sleep(.1) #Don't waste CPU-cycles
# Empty STDERR buffer
err = p.stderr.read()
if p.returncode != 0:
# The run_command() function is responsible for logging STDERR
print("Error: " + str(err))
Ten kod będzie wykonywany tak samo jak poprzednie odpowiedzi:
for line in run_command(cmd):
print(line)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-18 03:31:23
Rozdzielenie komendy początkowej dla subprocess
może być trudne i uciążliwe.
Użyj shlex.split()
, aby pomóc sobie.
Przykładowe polecenie
git log -n 5 --since "5 years ago" --until "2 year ago"
Kod
from subprocess import check_output
from shlex import split
res = check_output(split('git log -n 5 --since "5 years ago" --until "2 year ago"'))
print(res)
>>> b'commit 7696ab087a163e084d6870bb4e5e4d4198bdc61a\nAuthor: Artur Barseghyan...'
BEZ shlex.split()
kod wyglądałby następująco
res = check_output([
'git',
'log',
'-n',
'5',
'--since',
'5 years ago',
'--until',
'2 year ago'
])
print(res)
>>> b'commit 7696ab087a163e084d6870bb4e5e4d4198bdc61a\nAuthor: Artur Barseghyan...'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-18 20:05:19
Jeśli musisz uruchomić polecenie powłoki na wielu plikach, To mi się udało.
import os
import subprocess
# Define a function for running commands and capturing stdout line by line
# (Modified from Vartec's solution because it wasn't printing all lines)
def runProcess(exe):
p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
# Get all filenames in working directory
for filename in os.listdir('./'):
# This command will be run on each file
cmd = 'nm ' + filename
# Run the command and capture the output line by line.
for line in runProcess(cmd.split()):
# Eliminate leading and trailing whitespace
line.strip()
# Split the output
output = line.split()
# Filter the output and print relevant lines
if len(output) > 2:
if ((output[2] == 'set_program_name')):
print filename
print line
Edit: właśnie zobaczyłem rozwiązanie Maxa Perssona z sugestią J. F. Sebastiana. / Align = "left" /
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-01 15:54:55
Według @senderle, jeśli używasz python3. 6 Jak ja:
def sh(cmd, input=""):
rst = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, input=input.encode("utf-8"))
assert rst.returncode == 0, rst.stderr.decode("utf-8")
return rst.stdout.decode("utf-8")
sh("ls -a")
Będzie działać dokładnie tak, jak uruchomisz polecenie w bash
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-20 06:47:44
Tutaj rozwiązanie, działające, jeśli chcesz wydrukować wyjście, gdy proces jest uruchomiony lub nie.
Dodałem również bieżący katalog roboczy, przydał mi się nie raz.
Mam nadzieję, że rozwiązanie komuś pomoże:).
import subprocess
def run_command(cmd_and_args, print_constantly=False, cwd=None):
"""Runs a system command.
:param cmd_and_args: the command to run with or without a Pipe (|).
:param print_constantly: If True then the output is logged in continuous until the command ended.
:param cwd: the current working directory (the directory from which you will like to execute the command)
:return: - a tuple containing the return code, the stdout and the stderr of the command
"""
output = []
process = subprocess.Popen(cmd_and_args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
while True:
next_line = process.stdout.readline()
if next_line:
output.append(str(next_line))
if print_constantly:
print(next_line)
elif not process.poll():
break
error = process.communicate()[1]
return process.returncode, '\n'.join(output), error
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-29 23:32:10
Jeśli używasz modułu Pythona subprocess
, możesz obsługiwać STDOUT, STDERR i Kod polecenia osobno. Możesz zobaczyć przykład pełnej implementacji wywołującego polecenia. Oczywiście możesz go rozszerzyć za pomocą try..except
, jeśli chcesz.
Poniższa funkcja zwraca kod STDOUT, STDERR I Return, abyś mógł obsłużyć je w innym skrypcie.
import subprocess
def command_caller(command=None)
sp = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
out, err = sp.communicate()
if sp.returncode:
print(
"Return code: %(ret_code)s Error message: %(err_msg)s"
% {"ret_code": sp.returncode, "err_msg": err}
)
return sp.returncode, out, err
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-20 11:24:47
Eg, execute ('ls-ahl') zróżnicowane trzy / cztery możliwe zwroty i platformy OS:
- brak wyjścia, ale Uruchom pomyślnie
- wyjście pustej linii, Uruchom pomyślnie
- run failed
- wypuść coś, Uruchom pomyślnie
Funkcja poniżej
def execute(cmd, output=True, DEBUG_MODE=False):
"""Executes a bash command.
(cmd, output=True)
output: whether print shell output to screen, only affects screen display, does not affect returned values
return: ...regardless of output=True/False...
returns shell output as a list with each elment is a line of string (whitespace stripped both sides) from output
could be
[], ie, len()=0 --> no output;
[''] --> output empty line;
None --> error occured, see below
if error ocurs, returns None (ie, is None), print out the error message to screen
"""
if not DEBUG_MODE:
print "Command: " + cmd
# https://stackoverflow.com/a/40139101/2292993
def _execute_cmd(cmd):
if os.name == 'nt' or platform.system() == 'Windows':
# set stdin, out, err all to PIPE to get results (other than None) after run the Popen() instance
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
else:
# Use bash; the default is sh
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, executable="/bin/bash")
# the Popen() instance starts running once instantiated (??)
# additionally, communicate(), or poll() and wait process to terminate
# communicate() accepts optional input as stdin to the pipe (requires setting stdin=subprocess.PIPE above), return out, err as tuple
# if communicate(), the results are buffered in memory
# Read stdout from subprocess until the buffer is empty !
# if error occurs, the stdout is '', which means the below loop is essentially skipped
# A prefix of 'b' or 'B' is ignored in Python 2;
# it indicates that the literal should become a bytes literal in Python 3
# (e.g. when code is automatically converted with 2to3).
# return iter(p.stdout.readline, b'')
for line in iter(p.stdout.readline, b''):
# # Windows has \r\n, Unix has \n, Old mac has \r
# if line not in ['','\n','\r','\r\n']: # Don't print blank lines
yield line
while p.poll() is None:
sleep(.1) #Don't waste CPU-cycles
# Empty STDERR buffer
err = p.stderr.read()
if p.returncode != 0:
# responsible for logging STDERR
print("Error: " + str(err))
yield None
out = []
for line in _execute_cmd(cmd):
# error did not occur earlier
if line is not None:
# trailing comma to avoid a newline (by print itself) being printed
if output: print line,
out.append(line.strip())
else:
# error occured earlier
out = None
return out
else:
print "Simulation! The command is " + cmd
print ""
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 21:55:38
Wyjście może zostać przekierowane do pliku tekstowego, a następnie odczytane z powrotem.
import subprocess
import os
import tempfile
def execute_to_file(command):
"""
This function execute the command
and pass its output to a tempfile then read it back
It is usefull for process that deploy child process
"""
temp_file = tempfile.NamedTemporaryFile(delete=False)
temp_file.close()
path = temp_file.name
command = command + " > " + path
proc = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
if proc.stderr:
# if command failed return
os.unlink(path)
return
with open(path, 'r') as f:
data = f.read()
os.unlink(path)
return data
if __name__ == "__main__":
path = "Somepath"
command = 'ecls.exe /files ' + path
print(execute(command))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-22 15:06:06
Właśnie napisałem mały skrypt bash, aby to zrobić za pomocą curl
Https://gist.github.com/harish2704/bfb8abece94893c53ce344548ead8ba5
#!/usr/bin/env bash
# Usage: gdrive_dl.sh <url>
urlBase='https://drive.google.com'
fCookie=tmpcookies
curl="curl -L -b $fCookie -c $fCookie"
confirm(){
$curl "$1" | grep jfk-button-action | sed -e 's/.*jfk-button-action" href="\(\S*\)".*/\1/' -e 's/\&/\&/g'
}
$curl -O -J "${urlBase}$(confirm $1)"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-13 13:06:25
Chciałbym zaproponować simppl jako opcję do rozważenia. Jest to moduł, który jest dostępny przez pypi: pip install simppl
i został uruchomiony na python3.
simppl
pozwala użytkownikowi uruchamiać polecenia powłoki i odczytywać dane wyjściowe z ekranu.
Twórcy sugerują trzy rodzaje przypadków użycia:
- najprostsze użycie będzie wyglądało tak:
from simppl.simple_pipeline import SimplePipeline sp = SimplePipeline(start=0, end=100): sp.print_and_run('<YOUR_FIRST_OS_COMMAND>') sp.print_and_run('<YOUR_SECOND_OS_COMMAND>') ```
- aby uruchomić wiele poleceń jednocześnie użycie:
commands = ['<YOUR_FIRST_OS_COMMAND>', '<YOUR_SECOND_OS_COMMAND>'] max_number_of_processes = 4 sp.run_parallel(commands, max_number_of_processes) ```
- wreszcie, jeśli twój projekt używa modułu cli, możesz uruchomić bezpośrednio inny command_line_tool jako część potoku. Inne narzędzie będzie być uruchamiany z tego samego procesu, ale będzie on wyświetlany z dzienników jako kolejne polecenie w rurociągu. Umożliwia to płynniejsze debugowanie i refaktoryzacja narzędzi wywołanie innych narzędzi.
from example_module import example_tool sp.print_and_run_clt(example_tool.run, ['first_number', 'second_nmber'], {'-key1': 'val1', '-key2': 'val2'}, {'--flag'}) ```
Zauważ, że drukowanie na STDOUT/STDERR odbywa się za pomocą modułu logging
Pythona.
Oto Pełny kod pokazujący jak działa simppl:
import logging
from logging.config import dictConfig
logging_config = dict(
version = 1,
formatters = {
'f': {'format':
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
},
handlers = {
'h': {'class': 'logging.StreamHandler',
'formatter': 'f',
'level': logging.DEBUG}
},
root = {
'handlers': ['h'],
'level': logging.DEBUG,
},
)
dictConfig(logging_config)
from simppl.simple_pipeline import SimplePipeline
sp = SimplePipeline(0, 100)
sp.print_and_run('ls')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-19 09:59:46