2013-11-27 2 views
0

Кто-нибудь знает, что эквивалентно пакетному скрипту %* в python?% * эквивалент в python

Уточнение: в командном файле %* - все параметры, указанные в командной строке - это очень полезно, если вы хотите перенаправить параметры в другую программу.

Моя проблема в том, что я хочу, чтобы преобразовать один пакетный вызов питона вызова:

Пакетный вызов:

trial.bat %* 


, что является эквивалентом питон вызова (PS Я знаю, что могу просто пройти через весь sys.argv список и добавить параметры в некоторой строке и передать в пакетный файл, но я ищу более простое решение здесь)

Я попробовал следующее:

os.system('trial.bat '+sys.argv) 
os.system('trial.bat '+sys.argv[1:]) 

Но это не работает. Я пробовал аналогичную вещь, используя argparse. Это тоже не работает. Пожалуйста помоги.

ответ

4

sys.argv[1:] довольно близко. Дело в том, что argv - это список аргументов, а [1:] - это фрагмент списка, который снова является списком. Если вы хотите строку со всеми аргументами в сочетании, вы можете присоединиться к ним снова:

os.system('trial.bat ' + ' '.join(sys.argv[1:])) 

Или еще лучше, вы используете subprocess модуль, какой метод примем список аргументов:

subprocess.check_call(['trial.bat'] + sys.argv[1:]) 

Subprocess значительно более гибкий при обработке параметров и также будет вести себя аналогично разбору в argv. В качестве примера, при вызове сценария с аргументами foo "hello world" bar, ARGV будет содержать это:

>>> sys.argv[1:] 
['foo', 'hello world', 'bar'] 

Теперь, если мы должны были просто присоединиться к этому списку, мы получим одну строку

>>> ' '.join(sys.argv[1:]) 
'foo hello world bar' 

Как вам может видеть, информация составного аргумента hello world теряется, что приводит к совершенно иному значению.

При использовании subprocess, однако, вы сохраняете свой список и подпроцесс автоматически, обязательно передадите эти аргументы правильно вызываемой программе. Таким образом, вызываемая программа сможет получить hello world в качестве комбинированного аргумента.

+0

awesome..os.system ('trial.bat' + '' .join (sys.argv [1:])) работал на меня. – tejas

+0

Вам нужна оболочка для запуска командного файла, поэтому 'subprocess.check_call' не будет работать. – abarnert

+1

@abarnert Нет, пакетные файлы могут быть выполнены системой, им не нужно запускать оболочку. Это определенно работает. – poke

3

Вы хотите subprocess.Popen (или один из его удобных оберток):

import subprocess 
import sys 
process = subprocess.Popen(['trial.bat'] + sys.argv[1:]) 
process.wait() 

Это определенно предпочел os.system. Преимущество здесь состоит в том, что аргументы командной строки, которые могут потребоваться для цитирования, чтобы сохранить их значение, остаются в силе. Кроме того, эта альтернатива, вероятно, более безопасна, чем os.system, поскольку она позволяет избежать создания подоболочки.

+0

За исключением того, что вы не можете запустить файл '.bat' без оболочки. – abarnert

+0

Кроме того, зачем создавать 'Popen' только для того, чтобы называть' wait' на нем вместо того, чтобы просто делать 'call'? – abarnert

+0

«За исключением того, что вы не можете запустить .bat-файл без оболочки». можете ли вы показать документацию для этого? – nephi12

0

Если вы хотите использовать os.system, вам необходимо вручную установить командную строку.Python уже разобрал командную строку на отдельные аргументы (или MSVCRT сделал это от имени Python). Это означает, что вам нужно не просто конкатенировать их вместе, но и процитировать их соответствующим образом.

В stdlib ничего нет, что обрабатывает «правильно их цитировать» именно так, как хочет MSVCRT. Это отчасти потому, что цитирование Windows на самом деле неоднозначно; есть случаи, когда невозможно совершить кругосветное путешествие. Но для простых случаев будет использоваться либо цитирование в стиле POSIX (с shlex.quote), либо просто использование явных цитат вокруг каждого аргумента. Таким образом, любой из них:

args = ' '.join(shlex.quote(arg) for arg in [program] + sys.argv[1:]) 
args = ' '.join('"{}"'.format(arg) for arg in [program] + sys.argv[1:]) 

Тогда:

os.system(args) 

Но использование subprocess лучше os.system. Одна из причин заключается в том, что вам не нужно возиться с цитированием вещей; вы можете просто сделать это:

subprocess.check_call([program] + sys.argv[1:], shell=True) 

Кто-то еще нужно поместить список аргументов вместе в строке, поэтому он может быть передан в оболочку, но теперь, что «кто-то» является subprocess модуль, а не код ,

Смежные вопросы