Python脚本执行mv报target is not a directory但终端运行正常原因排查
问题原因
- 波浪号
~的路径展开是Shell专属功能:subprocess.run默认运行模式为shell=False,不会启动系统Shell解析命令,只会把传入的参数原样交给mv命令处理,因此~不会被替换为当前用户的家目录绝对路径,mv找不到字面意义上的~/Pictures/Wallpapers/目录就会报错。你手动复制命令到终端执行时,终端的Shell会提前完成~的展开,所以能正常运行。 - 潜在额外风险:使用
command.split(" ")拆分命令字符串的方式不可靠,只要路径中包含空格,就会把单一路径拆分为多个无效参数,也会引发命令执行错误。另外你当前的路径拼接逻辑没有添加路径分隔符,很容易出现路径拼接错误。
修复方案
方案1(推荐,无安全风险)
手动完成路径展开,直接构造参数列表传给subprocess.run,避免字符串拆分和Shell解析:
import os import subprocess # 正确拼接源文件路径,自动处理路径分隔符 src_path = os.path.join(cwd, sys.argv[2], "wallpaper.jpg") # 手动展开波浪号为绝对路径 dest_dir = os.path.expanduser("~/Pictures/Wallpapers/") # 直接传入参数列表 subprocess.run(["mv", src_path, dest_dir])
方案2(不推荐,存在命令注入风险)
开启shell=True参数,让subprocess启动Shell来解析命令,此时直接传入完整命令字符串即可,不需要拆分:
command = "mv " + cwd + sys.argv[2] + " wallpaper.jpg" + " ~/Pictures/Wallpapers/" subprocess.run(command, shell=True)
注意:如果sys.argv[2]的内容是外部用户可控的,开启shell=True可能会被利用执行恶意命令,非必要不建议使用该方案。
内容的提问来源于stack exchange,提问作者BaridunDuskhide
相关产品推荐
相关产品推荐

