Ik wil een functie schrijven die een shell-opdracht uitvoert en de uitvoer als een tekenreeksretourneert, ongeacht of het een fout- of succesbericht is. Ik wil gewoon hetzelfde resultaat krijgen als met de opdrachtregel.
Wat zou een codevoorbeeld zijn dat zoiets zou doen?
Bijvoorbeeld:
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'
Antwoord 1, autoriteit 100%
In alle officieel onderhouden versies van Python is de eenvoudigste benadering het gebruik van de subprocess.check_output
functie:
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
check_output
voert een enkel programma uit dat alleen argumenten als invoer gebruikt.1Het retourneert het resultaat precies zoals afgedrukt in stdout
. Als u invoer naar stdin
moet schrijven, gaat u verder met de secties run
of Popen
. Als je complexe shell-commando’s wilt uitvoeren, zie dan de opmerking over shell=True
aan het einde van dit antwoord.
De functie check_output
werkt in alle officieel onderhouden versies van Python. Maar voor recentere versies is een flexibelere aanpak beschikbaar.
Moderne versies van Python (3.5 of hoger): run
Als u Python 3,5 + gebruikt, en Not Achterwaartse compatibiliteit , de Nieuwe run
functie wordt aanbevolen door de officiële documentatie voor de meeste taken. Het biedt een zeer algemene, hoogwaardige API voor de subprocess
Module. Om de uitvoer van een programma vast te leggen, passeert u de subprocess.PIPE
vlag naar de stdout
trefwoord argument. Open vervolgens de stdout
Attribuut van de geretourneerde CompletedProcess
object:
>>> 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'
De retourwaarde is een bytes
object, dus als u een goede reeks wilt, moet u decode
het. Uitgaande van het genoemde proces retourneert een UTF-8-gecodeerde reeks:
>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Dit kan allemaal worden gecomprimeerd op een een-voering indien gewenst:
>>> 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'
Als u input wilt doorgeven aan de stdin
, kunt u een bytes
object geven aan de input
trefwoordargument:
>>> 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'
U kunt fouten vastleggen door stderr=subprocess.PIPE
(vastleggen naar result.stderr
) of stderr=subprocess.STDOUT
(vastleggen naar result.stdout
samen met reguliere uitvoer). Als u wilt dat run
een uitzondering genereert wanneer het proces een afsluitcode die niet nul is retourneert, kunt u check=True
doorgeven. (Of u kunt het returncode
attribuut van result
hierboven controleren.) Als beveiliging geen probleem is, kunt u ook complexere shell-commando’s uitvoeren door shell=True
zoals beschreven aan het einde van dit antwoord.
Latere versies van Python stroomlijnen het bovenstaande verder. In Python 3.7+ kan de bovenstaande one-liner als volgt worden gespeld:
>>> 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'
Het gebruik van run
op deze manier voegt een beetje complexiteit toe, vergeleken met de oude manier om dingen te doen. Maar nu kun je bijna alles doen wat je moet doen met alleen de functie run
.
Oudere versies van Python (3-3.4): meer over check_output
Als je een oudere versie van Python gebruikt, of een bescheiden achterwaartse compatibiliteit nodig hebt, kun je de functie check_output
gebruiken zoals hierboven kort beschreven. Het is beschikbaar sinds Python 2.7.
subprocess.check_output(*popenargs, **kwargs)
Het duurt dezelfde argumenten als Popen
(zie hieronder), en retourneert een tekenreeks die de uitvoer van het programma bevat. Het begin van dit antwoord heeft een meer gedetailleerd gebruiksvoorbeeld. In Python 3.5+ is check_output
gelijk aan het uitvoeren van run
met check=True
en stdout=PIPE
, en terugkeren alleen het kenmerk stdout
.
U kunt stderr=subprocess.STDOUT
doorgeven om ervoor te zorgen dat foutmeldingen worden opgenomen in de geretourneerde uitvoer. Als beveiliging geen probleem is, kunt u ook complexere shell-opdrachten uitvoeren door shell=True
door te geven, zoals beschreven aan het einde van dit antwoord.
Als u stderr
moet pipen of invoer aan het proces moet doorgeven, is check_output
niet geschikt voor deze taak. Zie in dat geval de Popen
voorbeelden hieronder.
Complexe applicaties en oudere versies van Python (2.6 en lager): Popen
Als je diepe achterwaartse compatibiliteit nodig hebt, of als je meer geavanceerde functionaliteit nodig hebt dan check_output
of run
bieden, moet je rechtstreeks met Popen
objecten, die de low-level API inkapselen voor subprocessen.
De Popen
-constructor accepteert ofwel een enkele opdrachtzonder argumenten, of een lijstmet een opdracht als eerste item, gevolgd door een willekeurig nummer argumenten, elk als een afzonderlijk item in de lijst. shlex.split
kan helpen bij het ontleden van tekenreeksen in de juiste opmaak lijsten. Popen
-objecten accepteren ook een groot aantal verschillende argumentenvoor proces-IO-beheer en configuratie op laag niveau.
Om invoer te verzenden en uitvoer vast te leggen, is communicate
bijna altijd de voorkeursmethode. Zoals in:
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
Of
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
Als u stdin=PIPE
instelt, kunt u met communicate
ook gegevens doorgeven aan het proces via 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
Let op Het antwoord van Aaron Hall, wat aangeeft dat je op sommige systemen mogelijk stdout
, stderr
en stdin
allemaal naar PIPE
(of DEVNULL
) om communicate
om helemaal te werken.
In sommige zeldzame gevallen heeft u mogelijk complexe, realtime uitvoerregistratie nodig. Vartec‘s antwoord suggereert een weg vooruit, maar andere methoden dan communicate
zijn vatbaar voor impasses als niet zorgvuldig gebruikt.
Zoals bij alle bovenstaande functies, wanneer beveiliging geen probleem is, kunt u meer complexe schaalopdrachten uitvoeren door shell=True
te passeren.
Opmerkingen
1. Running Shell-opdrachten: de shell=True
argument
Normaal gesproken, elke oproep naar run
, check_output
of de Popen
constructor voert een enkel programma uit. Dat betekent geen mooie book-stijlpijpen. Als u complexe Shell-opdrachten wilt uitvoeren, kunt u doorgeven shell=True
, die alle drie de acties ondersteunen. Bijvoorbeeld:
>>> subprocess.check_output('cat books/* | wc', shell=True, text=True)
' 1299377 17005208 101299376\n'
Doe dit echter echter verhoogt beveiligingsproblemen . Als u iets meer doet dan lichte scripting, bent u misschien beter af, belt u elk proces afzonderlijk en passeert u de uitvoer van elk als een invoer naar de volgende, via
run(cmd, [stdout=etc...], input=other_output)
of
Popen(cmd, [stdout=etc...]).communicate(other_output)
De verleiding om direct aan te sluiten buizen is sterk; Weersta het. Anders ziet u waarschijnlijk deadlocks of moet u hacky dingen doen zoals dit .
Antwoord 2, Autoriteit 14%
Dit is veel eenvoudiger, maar werkt alleen op Unix (inclusief Cygwin) en Python2.7.
import commands
print commands.getstatusoutput('wc -l file')
Het retourneert een tuple met de (return_value, output).
Gebruik in plaats daarvan de module subprocess
voor een oplossing die zowel in Python2 als Python3 werkt:
from subprocess import Popen, PIPE
output = Popen(["date"],stdout=PIPE)
response = output.communicate()
print response
Antwoord 3, autoriteit 8%
Zoiets:
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
Merk op, dat ik stderr omleid naar stdout, het is misschien niet precies wat je wilt, maar ik wil ook foutmeldingen.
Deze functie levert regel voor regel op wanneer ze binnenkomen(normaal zou je moeten wachten tot het subproces is voltooid om de uitvoer als geheel te krijgen).
Voor jouw geval zou het gebruik zijn:
for line in runProcess('mysqladmin create test -uroot -pmysqladmin12'.split()):
print line,
Antwoord 4, autoriteit 6%
Ik had hetzelfde probleem, maar bedacht een heel eenvoudige manier om dit te doen:
import subprocess
output = subprocess.getoutput("ls -l")
print(output)
Hopelijk helpt het
Opmerking: deze oplossing is specifiek voor Python3 omdat subprocess.getoutput()
niet werkt in Python2
Antwoord 5, autoriteit 5%
Het antwoord van Vartecleest niet alle regels, dus heb ik een versie gemaakt die dat wel deed:
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
Gebruik is hetzelfde als het geaccepteerde antwoord:
command = 'mysqladmin create test -uroot -pmysqladmin12'.split()
for line in run_command(command):
print(line)
Antwoord 6, autoriteit 5%
Dit is een lastigemaar supereenvoudigeoplossing die in veel situaties werkt:
import os
os.system('sample_cmd > tmp')
print(open('tmp', 'r').read())
Een tijdelijk bestand (hier is tmp) wordt gemaakt met de uitvoer van de opdracht en u kunt daaruit uw gewenste uitvoer lezen.
Extra opmerking bij de opmerkingen:
U kunt het tmp-bestand verwijderen in het geval van een eenmalige taak. Als u dit meerdere keren moet doen, hoeft u de tmp niet te verwijderen.
os.remove('tmp')
Antwoord 7, autoriteit 2%
U kunt de volgende commando’s gebruiken om elk shell-commando uit te voeren. Ik heb ze op ubuntu gebruikt.
import os
os.popen('your command here').read()
Opmerking:dit is verouderd sinds python 2.6. Nu moet je subprocess.Popen
gebruiken. Hieronder is het voorbeeld
import subprocess
p = subprocess.Popen("Your command", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
print p.split("\n")
Antwoord 8
Uw kilometerstand kan variëren, ik probeerde @senderle’s draai aan Vartec’s oplossing in Windows op Python 2.6.5, maar ik kreeg fouten en geen enkele andere oplossing werkte. Mijn fout was: WindowsError: [Error 6] The handle is invalid
.
Ik ontdekte dat ik PIPE aan elke handle moest toewijzen om de output te krijgen die ik verwachtte – het volgende werkte voor mij.
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()
en bel zo, ([0]
krijgt het eerste element van de tuple, stdout
):
run_command('tracert 11.1.0.1')[0]
Na meer te hebben geleerd, geloof ik dat ik deze pijpargumenten nodig heb omdat ik aan een aangepast systeem werk dat verschillende handvatten gebruikt, dus ik moest alle std’s rechtstreeks besturen.
Als u console-pop-ups wilt stoppen (met Windows), doet u dit:
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')
Antwoord 9
Ik had een iets andere smaak van hetzelfde probleem met de volgende vereisten:
- Vastleggen en retourneren staald-berichten terwijl ze zich ophopen in de stdout-buffer (d.w.z. in realtime).
- @vartec opgelost deze pythonisch met zijn gebruik van generatoren en de ‘opbrengst’
hierboven
- @vartec opgelost deze pythonisch met zijn gebruik van generatoren en de ‘opbrengst’
- Druk alle stDout-lijnen (, zelfs als het procesuitgangen vóór de stdout-buffer volledig kan worden gelezen )
- Verspil geen CPU-cycli die het proces op hoge frequentie polderen
- Controleer de retourcode van het subprocess
- Afdrukken Stderr (gescheiden van stdout) als we een non-zero fout retourcode krijgen.
Ik heb gecombineerd en aangepreend eerdere antwoorden om met het volgende te komen:
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))
Deze code wordt op dezelfde manier uitgevoerd als eerdere antwoorden:
for line in run_command(cmd):
print(line)
Antwoord 10
Het splitsen van de initiële opdracht voor het subprocess
kan lastig en omslachtig zijn.
Gebruik shlex.split()
om jezelf te helpen.
Voorbeeldopdracht
git log -n 5 --since "5 years ago" --until "2 year ago"
De code
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...'
Zonder shlex.split()
zou de code er als volgt uitzien
res = check_output([
'git',
'log',
'-n',
'5',
'--since',
'5 years ago',
'--until',
'2 year ago'
])
print(res)
>>> b'commit 7696ab087a163e084d6870bb4e5e4d4198bdc61a\nAuthor: Artur Barseghyan...'
Antwoord 11
Hier een oplossing die werkt als u output wilt afdrukken terwijl het proces loopt of niet.
Ik heb ook de huidige werkdirectory toegevoegd, het was meer dan eens nuttig voor mij.
In de hoop dat de oplossing iemand zal helpen :).
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
Antwoord 12
Als je een shell-opdracht op meerdere bestanden moet uitvoeren, was dit voor mij de juiste oplossing.
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
Bewerken: ik zag net de oplossing van Max Persson met de suggestie van J.F. Sebastian. Ging door en nam dat op.
Antwoord 13
Volgens @senderle, als je python3.6 gebruikt zoals ik:
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")
Werkt precies zoals u het commando in bash uitvoert
Antwoord 14
Als u de subprocess
python-module gebruikt, kunt u de STDOUT-, STDERR- en retourcode van de opdracht afzonderlijk verwerken. U kunt een voorbeeld zien van de volledige implementatie van de opdrachtaanroeper. Natuurlijk kun je het uitbreiden met try..except
als je wilt.
De onderstaande functie retourneert de STDOUT-, STDERR- en Return-code zodat u ze in het andere script kunt verwerken.
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
Antwoord 15
Ik wil simpppl als een optie voor overweging voor rekening houden. Het is een module die beschikbaar is via PYPI: pip install simppl
en is uitgevoerd op Python3.
simppl
stelt de gebruiker toe om Shell-opdrachten uit te voeren en de uitvoer te lezen van het scherm.
De ontwikkelaars suggereren drie soorten gebruikszaken:
- Het eenvoudigste gebruik zal er als volgt uitzien:
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>') ```
- Om meerdere opdrachten tegelijkertijd te gebruiken, gebruikt u:
commands = ['<YOUR_FIRST_OS_COMMAND>', '<YOUR_SECOND_OS_COMMAND>'] max_number_of_processes = 4 sp.run_parallel(commands, max_number_of_processes) ```
- Ten slotte, als uw project de CLI-module gebruikt, kunt u direct een andere commando_line_tool uitvoeren als onderdeel van een pijplijn. De andere tool zal
worden uitgevoerd vanuit hetzelfde proces, maar het verschijnt van de logs als
een ander commando in de pijplijn. Hierdoor kunnen soepeler debuggen en
Refactoring van tools die andere hulpmiddelen oproepen.from example_module import example_tool sp.print_and_run_clt(example_tool.run, ['first_number', 'second_nmber'], {'-key1': 'val1', '-key2': 'val2'}, {'--flag'}) ```
Houd er rekening mee dat het afdrukken naar STDOUT/STDERR via de logging
-module van Python gaat.
Hier is een volledige code om te laten zien hoe simppl werkt:
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')
Antwoord 16
Gebruik op Python 3.7+subprocess.run
en geef capture_output=True
:
door
import subprocess
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True)
print(repr(result.stdout))
Dit levert bytes op:
b'hello world\n'
Als u wilt dat het de bytes naar een tekenreeks converteert, voegt u text=True
toe:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, text=True)
print(repr(result.stdout))
Hiermee worden de bytes gelezen met uw standaardcodering:
'hello world\n'
Als u een andere codering handmatig moet specificeren, gebruikt u encoding="your encoding"
in plaats van text=True
:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, encoding="utf8")
print(repr(result.stdout))
Antwoord 17
Execute (‘ls -ahl’)
Gedifferentieerde drie / vier mogelijke rendementen en OS-platforms:
- Geen uitgang, maar loop met succes
- Uitvoer lege regel, loop met succes
- RUN FAILED
- Output Iets, voer succesvol af
functie hieronder
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 ""
Antwoord 18
De uitvoer kan worden omgeleid naar een tekstbestand en het vervolgens teruglezen.
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))
Antwoord 19
heeft zojuist een klein bash-script geschreven om dit te doen met 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)"