在Python中使用子进程

1 投票
3 回答
8049 浏览
提问于 2025-04-16 15:50

我正在创建一个Django应用程序,用户可以上传一个文件。我想使用subprocess模块来处理这个文件,把它作为参数传递给一个外部脚本,然后获取结果。请问subprocess.Popen的调用格式应该是什么样的?我还想给脚本传递一个选项,比如-a。

换句话说,subprocess.Popen的调用应该如何写,才能对应一个类似于下面的命令行:

./myscript -option file

另外,我在运行这个脚本时,路径方面有没有什么问题?非常感谢。

这是我在views.py中使用的代码。我只是想看看一个简单的cp命令是否能工作,以及如何传递参数:

def upload_file(request):

    if request.method == 'POST':
    form=UploadFileForm()        
    form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/upload')
    else:
        form = UploadFileForm()
    return render_to_response('upload_file.html', {'form': form})

def handle_uploaded_file(f):

    p=subprocess.Popen(['/bin/cp',f , '/home/dutzy/Desktop'])

3 个回答

1

request.FILES['file'] 不是一个字符串类型的文件名,而是一个 UploadedFile 对象。你可以查看Django的文档,了解你可以对这个对象做些什么。

试图获取文件路径并执行复制操作是不太好的做法,因为这样在远程用户的情况下会出问题。在这个过程中,网页浏览器会将文件数据上传到你的服务器,然后服务器再把这些数据传给Django,Django会创建一个UploadedFile对象来处理它。如果你想简单地把这个文件复制到磁盘上,你需要写类似下面的代码:

def handle_uploaded_file(f):
    destination = open('path/to/store/at/' + f.name, 'wb+')
    for chunk in f.chunks():
        destination.write(chunk)
    destination.close()

如果你不想使用上传时的文件名,可以用其他名字代替 f.name。如果你想对上传的文件执行某个命令,首先要把它保存到某个地方(可能是临时文件),然后再用 subprocess.Popen 来运行这个命令。

1

你只需要传递一个元组或者列表,里面包含你的二进制文件名(可以是$PATH中的路径,或者相对路径)和它的参数。

import subprocess
p = subprocess.Popen(('./myscript', '-option', 'file'))
5

subprocess.Popen 的语法其实很简单:

subprocess.Popen(['./myscript', '-option', 'file'])

你只需要看看里面的例子,就能明白它的用法了。

撰写回答