Python subprocess.call - 向subprocess.call添加变量

2 投票
3 回答
10656 浏览
提问于 2025-04-17 18:59

我正在尝试用Python写一个简单的程序,目的是把我下载文件夹里的所有音乐文件移动到我的音乐文件夹里。我用的是Windows系统,虽然我可以通过命令提示符来移动文件,但我遇到了这个错误:

WindowsError: [Error 2] 系统找不到指定的文件

这是我的代码:

#! /usr/bin/python

import os 
from subprocess import call

def main():
    os.chdir("C:\\Users\Alex\Downloads") #change directory to downloads folder

    suffix =".mp3"    #variable holdinng the .mp3 tag
    fnames = os.listdir('.')  #looks at all files

    files =[]  #an empty array that will hold the names of our mp3 files

    for fname in fnames:  
        if fname.endswith(suffix):
            pname = os.path.abspath(fname)
            #pname = fname
            #print pname

            files.append(pname)  #add the mp3 files to our array
    print files

    for i in files:
        #print i 
        move(i)

def move(fileName):
    call("move /-y "+ fileName +" C:\Music")
    return

if __name__=='__main__':main()

我查阅了subprocess库和很多其他的文章,但我还是不知道自己哪里出错了。

3 个回答

0

我不直接回答你的问题,但对于这种任务,plumbum 是个很不错的选择,可以让你的生活轻松很多。subprocess 的使用方式不是特别直观。

0

可能会有几个问题:

  1. fileName 可能包含空格,这样 move 命令就只能看到文件名的一部分。

  2. 如果 move 是一个内部命令,你可能需要加上 shell=True 来运行它:

from subprocess import check_call

check_call(r"move /-y C:\Users\Alex\Downloads\*.mp3 C:\Music", shell=True)

要把 .mp3 文件从下载文件夹移动到音乐文件夹,而不使用 subprocess

from glob import glob
from shutil import move

for path in glob(r"C:\Users\Alex\Downloads\*.mp3"):
    move(path, r"C:\Music")
7

subprocess.call 方法需要一个参数列表,而不是用空格分开的字符串,除非你特别告诉它使用 shell,但如果字符串中包含用户输入的内容,这样做是不推荐的。

最好的做法是把命令构建成一个列表。

比如:

cmd = ["move", "/-y", fileName, "C:\Music"]
call(cmd)

这样做还可以更方便地传递带有空格的参数(比如路径或文件)给被调用的程序。

这两种方法在 subprocess 文档 中都有说明。

你可以传入一个用分隔符分开的字符串,但这样你就得让 shell 来处理这些参数。

call("move /-y "+ fileName +" C:\Music", shell=True)

另外,对于移动文件来说,Python 里有一个命令可以做到这一点,那就是 shutil.move

撰写回答