web-dev-qa-db-fra.com

Comment rediriger la sortie avec un sous-processus en Python?

Ce que je fais dans la ligne de commande:

cat file1 file2 file3 > myfile

Ce que je veux faire avec python:

import subprocess, shlex
my_cmd = 'cat file1 file2 file3 > myfile'
args = shlex.split(my_cmd)
subprocess.call(args) # spits the output in the window i call my python program
83
catatemypythoncode

UPDATE: os.system est déconseillé, même s'il est toujours disponible dans Python 3.


Utilisez os.system:

os.system(my_cmd)

Si vous voulez vraiment utiliser un sous-processus, voici la solution (principalement extraite de la documentation relative au sous-processus):

p = subprocess.Popen(my_cmd, Shell=True)
os.waitpid(p.pid, 0)

OTOH, vous pouvez totalement éviter les appels système:

import shutil

with open('myfile', 'w') as outfile:
    for infile in ('file1', 'file2', 'file3'):
        shutil.copyfileobj(open(infile), outfile)
21
Marcelo Cantos

Pour répondre à votre question initiale, pour rediriger la sortie, transmettez simplement un descripteur de fichier ouvert pour l'argument stdout à subprocess.call:

# Use a list of args instead of a string
input_files = ['file1', 'file2', 'file3']
my_cmd = ['cat'] + input_files
with open('myfile', "w") as outfile:
    subprocess.call(my_cmd, stdout=outfile)

Mais, comme d'autres l'ont souligné, l'utilisation d'une commande externe telle que cat à cette fin est totalement étrangère.

220
Ryan Thompson

@PoltoS Je veux joindre des fichiers, puis traiter le fichier résultant. Je pensais que l'utilisation du chat était l'alternative la plus simple. Y at-il une meilleure façon/Pythonic de le faire?

Bien sûr: 

with open('myfile', 'w') as outfile:
    for infilename in ['file1', 'file2', 'file3']:
        with open(infilename) as infile:
            outfile.write(infile.read())
4

Un cas intéressant serait de mettre à jour un fichier en y ajoutant un fichier similaire. Il ne serait alors pas nécessaire de créer un nouveau fichier dans le processus. C'est particulièrement utile dans le cas où un fichier volumineux doit être ajouté. Voici une possibilité en utilisant la ligne de commande teminal directement à partir de python.

import subprocess32 as sub

with open("A.csv","a") as f:
    f.flush()
    sub.Popen(["cat","temp.csv"],stdout=f)
0
DJJ
size = 'ffprobe -v error -show_entries format=size -of default=noprint_wrappers=1:nokey=1 dump.mp4 > file'
proc = subprocess.Popen(shlex.split(size), Shell=True)
time.sleep(1)
proc.terminate() #proc.kill() modify it by a suggestion
size = ""
with open('file', 'r') as infile:
    for line in infile.readlines():
        size += line.strip()

print(size)
os.remove('file')

Lorsque vous utilisez sous-processus , le processus doit être tué.Ceci est un exemple.Si vous ne tuez pas le processus, fichier sera vide et vous ne pourrez rien lire.Il peut fonctionner sous Windows . Je ne peux pas m'assurer qu'il puisse fonctionner sous Unix.

0
wyx