【问题标题】:Have I found a bug on subprocess.run? [duplicate]我在 subprocess.run 上发现错误了吗? [复制]
【发布时间】:2021-04-06 07:45:15
【问题描述】:

我有以下程序

import os
import sys
import subprocess
from pathlib import Path

program = subprocess.check_output("which gphotos-sync", shell=True).decode().strip()

home = Path(os.path.expanduser("~")) / "photos"

args = [
  "--ntfs",
  "--retry-download",
  "--skip-albums",
  "--photos-path ".",
  "--log-level", "DEBUG",
]

env = os.environ.copy()
env["LC_ALL"] = "en_US.UTF-8"

for p in home.glob("*/*"):
  print([program, *args, str(p.relative_to(home))])
  subprocess.run([program, *args, str(p.relative_to(home))], cwd=home, shell=True, env=env, stdout=sys.stdout, stderr=subprocess.STDOUT)

打印出来的

['/home/ubuntu/.local/bin/gphotos-sync', '--ntfs', '--retry-download', '--skip-albums', '--photos-path .', '--log-level DEBUG', 'rodrigo/0']
usage: gphotos-sync [-h] [--album ALBUM] [--log-level LOG_LEVEL] [--logfile LOGFILE] [--compare-folder COMPARE_FOLDER] [--favourites-only] [--flush-index] [--rescan] [--retry-download]
                    [--skip-video] [--skip-shared-albums] [--album-date-by-first-photo] [--start-date START_DATE] [--end-date END_DATE] [--db-path DB_PATH] [--albums-path ALBUMS_PATH]
                    [--photos-path PHOTOS_PATH] [--use-flat-path] [--omit-album-date] [--new-token] [--index-only] [--skip-index] [--do-delete] [--skip-files] [--skip-albums] [--use-hardlinks]
                    [--no-album-index] [--case-insensitive-fs] [--max-retries MAX_RETRIES] [--max-threads MAX_THREADS] [--secret SECRET] [--archived] [--progress] [--max-filename MAX_FILENAME]
                    [--ntfs]
                    root_folder

如您所见,gphotos-sync 需要root_folder(最后一个参数)。但是如果我手动运行打印的命令行,程序就可以正常工作

/home/ubuntu/.local/bin/gphotos-sync --ntfs --retry-download --skip-albums --photos-path . --log-level DEBUG rodrigo/0

我错过了什么吗?

【问题讨论】:

  • "--photos-path ".", 无疑是错误的。无论是否将其更改为 "--photos-path", "." 是您需要的唯一更改,没有它,代码就不可能正常工作。
  • 除此之外:shell=True 是怎么回事?这使得只有第一个参数被视为代码;随后的参数是该代码的参数,但由于代码/home/ubuntu/.local/bin/gphotos-sync查看它的参数是什么,这意味着所有其他参数都被忽略了。跨度>
  • 除此之外:不要使用 which 缓存 PATH 查找。这在 shell 中也是不好的做法(它比 shell 的内置 PATH 查找缓存慢得多),在 Python 中也同样糟糕。
  • @CharlesDuffy 所以我不需要shell=True?我可以直接在process.run 上调用gphotos-sync 吗?我会试试的,谢谢你的反馈。
  • 如果你想让它和shell=True一起工作,你需要让它像['gphotos-sync "$@"', 'sh', *args, str(p.relative_to(home))]一样(第一个列表元素是一个shell脚本,第二个列表元素是$0 shell 脚本,第三个及以后是$1$2 等,所以"$@" 扩展到它们的整个集合),但关闭shell=True 绝对是更好的方法。

标签: python python-3.x


【解决方案1】:

当一个选项接受一个参数时,它们要么需要是单独的参数,要么你必须使用--option=parameter 语法。不能将它们放在以空格分隔的同一个参数中。

应该是这样的:

args = [
  "--ntfs",
  "--retry-download",
  "--skip-albums",
  "--photos-path", ".",
  "--log-level", "DEBUG",
]

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 2014-09-12
  • 1970-01-01
  • 2016-06-27
  • 1970-01-01
  • 2012-08-20
相关资源
最近更新 更多