Python:使用Subprocess复制文件

时间:2014-02-27 20:18:17

标签: python subprocess cp

如果我错了,请纠正我。 目标:通过产生复制文件到另一个进程(因此实际复制不会“锁定”调用它的进程)。

cmd = ['cp', '/Users/username/Pictures/2Gb_ImageFile.tif', '/Volume/HugeNetworkDrive/VerySlow/Network/Connection/Destination.tif']

def copyWithSubprocess(cmd):        
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

copyWithSubprocess(cmd)

2 个答案:

答案 0 :(得分:1)

在Python中处理复杂异步进程的最简单方法是使用multiprocessing库,该库专门用于支持此类任务,并且具有与threading模块非常相似的接口(实际上)我编写的代码可以在多线程和多处理操作之间切换,主要是通过导入一个库或另一个库,但这需要对模块的哪些部分使用相当严格的限制。)

[编辑:删除了关于线程的虚假建议并使我的开场断言不那么夸张]

答案 1 :(得分:1)

Popen(cmd, stdout=PIPE, stderr=PIPE)不会“锁定”您的父进程。

如果由于完整的管道缓冲区产生足够的输出,

cmd可能会停止运行。如果要丢弃子流程'输出,请使用DEVNULL代替PIPE

import os
from subprocess import Popen, STDOUT

DEVNULL = open(os.devnull, 'wb') #NOTE: it is already defined in Python 3.3+
p = Popen(cmd, stdout=DEVNULL, stderr=STDOUT)
# ...

如果你想在不阻塞主线程的情况下处理输出,那么你可以使用几种方法:fcntlselect,命名管道与iocp,threads。后者是一种更便携的方式:

p = Popen(cmd, stdout=PIPE, stderr=PIPE, bufsize=-1)
bind(p.stdout, stdout_callback)
bind(p.stderr, stderr_callback)
# ...

其中bind()函数:

from contextlib import closing
from functools import partial
from threading import Thread

def bind(pipe, callback, chunksize=8192):
    def consume():
        with closing(pipe):
            for chunk in iter(partial(pipe.read, chunksize), b''):
                callback(chunk)
    t = Thread(target=consume)
    t.daemon = True
    t.start()
    return t

在不阻塞主线程的情况下,您不需要外部进程来复制Python中的文件:

import shutil
from threading import Thread

Thread(target=shutil.copy, args=['source-file', 'destination']).start()

Python可以在I / O期间释放GIL,因此复制同时发生并与主线程并行发生。

您可以将它与使用多个进程的脚本进行比较:

import shutil
from multiprocessing import Process

Process(target=shutil.copy, args=['source-file', 'destination']).start()

如果您想在程序死亡时取消复制,请将thread_or_process.daemon属性设置为True