sys.argv при звонке python с - c - PullRequest
1 голос
/ 24 марта 2020

Рассмотрим следующий короткий фрагмент python (3.8):

import subprocess


def call_subprocess_command(*command: str):
    with subprocess.Popen(args=command, stdout=subprocess.PIPE, text=True) as process:
        for line in iter(process.stdout.readline, ""):
            print(line)



call_subprocess_command("python", "-c", "import sys; print(sys.argv)", "--test", "foo")

Это напечатает ['-c', '--test', 'foo']. Я хочу, чтобы он печатал только ['--test', 'foo'].

Мне это нужно, потому что я динамически вычисляю команду для запуска внутри контейнера docker. Однако синтаксический анализатор вызываемого кода всегда прерывается, потому что он получает аргумент «- c», с которым он не знает, как обращаться:

call_subprocess_command("python", "-c", 
"import argparse; parser=argparse.ArgumentParser(); parser.add_argument('test'); print(parser.parse_args())",
 "--test", "foo")

Это приводит к тому, что использование выводится в stderr, и он анализирует "- c" как значение для "test":

usage: -c [-h] test
-c: error: unrecognized arguments: --test

Мой текущий обходной путь использует аргументы только для ключевых слов ("--test"), но Я действительно хотел бы избавиться от этого "- c", если это возможно.

call_subprocess_command("python", "-c", 
"import argparse; parser=argparse.ArgumentParser(); parser.add_argument('--test'); print(parser.parse_args())",
 "--test", "foo")

Это приводит к тому, что я хочу:

Namespace(test='foo')

Я не совсем понимаю, почему это работает, потому что теперь, кажется, игнорирует "- c". Если я добавлю еще один параметр, о котором он не знает, например, «--bar», он снова вылетает, хотя «- c» также является параметром, о котором он не знает:

call_subprocess_command("python", "-c",
 "import argparse; parser=argparse.ArgumentParser(); parser.add_argument('--test'); print(parser.parse_args())",
 "--test", "foo", "--bar")
usage: -c [-h] [--test TEST]
-c: error: unrecognized arguments: --bar

Итак, мои вопросы:

  1. Как мне избавиться от аргумента "- c", присутствующего в подпроцессе 'sys.argv?
  2. Почему может argparse иногда игнорировать "- c", а иногда нет?

1 Ответ

4 голосов
/ 24 марта 2020

Как поясняется в комментариях, argparse использует sys.argv[0] в качестве prog и анализирует sys.argv[1:].

Это может быть понятнее, если я укажу параметр prog, который затем заменит значение по умолчанию '- c':

1119:~/mypy$ python3 -c 'import argparse; p=argparse.ArgumentParser(prog="PROG");print(p.parse_args())' --test foobar
usage: PROG [-h]
PROG: error: unrecognized arguments: --test foobar

При обычном использовании сценария sys.argv[0] - это Название сценария. Здесь «имя сценария» равно «- c».

С помощью сценария, повторяющего sys.argv:

1119:~/mypy$ python3 echo.py --test foobar
['echo.py', '--test', 'foobar']
...