gpt4 book ai didi

batch-file - 完美地批量转发参数

转载 作者:行者123 更新时间:2023-12-04 02:03:40 37 4
gpt4 key购买 nike

我有一个小的python脚本:

# args.py
import sys; print(sys.argv)


如何编写将所有参数转发到此脚本的 .bat包装文件?

为了从测试中删除我的shell,我将以以下方式调用它:

import subprocess
import sys
def test_bat(*args):
return subprocess.check_output(['args.bat'] + list(args), encoding='ascii')




obvious choice of batch file



@echo off
python args.py %*


适用于简单情况:

>>> test_bat('a', 'b', 'c')
"['args.py', 'a', 'b', 'c']\n"
>>> test_bat('a', 'b c')
"['args.py', 'a', 'b c']\n"


但是当尝试使用任意字符串时,很快就会崩溃:

>>> test_bat('a b', 'c\n d')
"['args.py', 'a b', 'c']\n" # missing d
>>> test_bat('a', 'b^^^^^c')
"['args.py', 'a', 'b^c']\n" # missing ^^^^


甚至有可能使 bat文件的参数保持不变吗?



为了证明不是引起问题的 subprocess-请尝试使用

def test_py(*args):
return subprocess.check_output([sys.executable, 'args.py'] + list(args), encoding='ascii')


所有测试的表现均符合预期



类似问题:


Get list of passed arguments in Windows batch script (.bat)-不解决无损转发
Redirecting passed arguments to a windows batch file-解决与我的问题相同的想法,但作为上述内容的重复被错误地关闭,并且测试用例不清晰
Forwarding all batch file parameters to inner command-问题不考虑极端情况,接受的答案对他们不起作用

最佳答案

简而言之:由于cmd.exe解释参数的方式,没有可靠的方式通过批处理文件按原样传递参数。请注意,即使您使用不要求外壳程序参与的API调用批处理文件,也要始终执行cmd.exe,因为它是执行批处理文件所需的解释器。

简而言之,这个问题是:


在Windows上,出于技术原因,调用外部程序需要使用命令行作为单个字符串。因此,即使使用基于数组的,无外壳的调用外部程序的方式,也需要自动编写嵌入了各个参数的命令行。


例如,Python的subprocess.check_output()分别接受目标可执行文件及其参数作为数组的元素,如问题所示。
目标可执行文件可以使用在幕后自动编写的命令行直接调用,而无需使用平台的外壳作为中介(例如,Python的os.system()调用的方式)-除非目标可执行文件本身发生这种情况需要该shell作为执行解释器,对于批处理文件,cmd.exe就是这种情况。

编写命令行需要对嵌入的"字符进行选择性的双引号和转义。嵌入各个参数时;通常涉及:


使用封闭的双引号("..."),但仅在包含空格(空格)的参数周围。
将嵌入式双引号转义为\"
值得注意的是,没有其他字符会触发双引号或个人转义,即使这些字符对于给定的shell可能具有特殊含义。

尽管此方法对大多数外部程序都有效,但对于批处理文件却不能可靠地起作用:


不幸的是,cmd.exe不会将参数视为文字,而是将其解释为您已在交互式控制台中提交了批处理文件调用(命令提示符)。
结合命令行的构成方式(如上所述),这会导致以多种方式误解参数并完全中断调用。


主要问题是cmd.exe看到的在命令行中未加引号的参数可能会中断调用,即,如果它们包含诸如&|><之类的字符。
即使调用没有中断,诸如^之类的字符也可能会被误解。


请参阅以下有关有问题的参数的特定示例。

尝试使用嵌入式引号解决调用方的问题-例如,在Python中使用'"^^^^^"作为参数-不起作用,因为大多数语言(包括Python)都使用\"来隐藏"字符,而cmd.exe不能识别(只能识别"")。


假设地,您可以在无空格的参数中艰难地^-转义单个字符,但不仅麻烦,而且仍不能解决所有问题-参见下文。

Jeb's answer值得称赞的是解决了批处理文件中的某些问题,但它非常复杂,也无法解决所有问题-请参阅下一点。

无法解决以下基本限制:


cmd.exe基本上不能处理带有嵌入式换行符(换行符)的参数:


解析参数列表仅在遇到的第一个换行符处停止。
CR(0xD)字符。孤立地被悄悄移除。

不能禁止将%解释为环境变量引用(例如%OS%)的一部分:


%%无济于事,因为奇怪的是,不幸的是,交互式cmd.exe会话的解析规则适用于(!),其中抑制扩展的唯一方法是采用“变量名破坏器技巧”,例如% ^ OS%,仅在不带引号的参数中起作用-在带双引号的参数中,您根本无法阻止扩展。
如果您的环境很幸运,变量恰好不存在;然后将令牌保留为空白(例如%NoSuchVar%%No Such Var%(请注意cmd.exe确实支持带空格的变量名称))。





不含空格的参数示例,这些参数会中断批处理文件的调用或导致值的不必要更改:


^^^^^


无引号的字符串中的^cmd.exe的转义字符,用于转义下一个字符,即将其视为文字;因此,^^代表一个文字单精度^,因此上面的结果为^^,最后一个^被丢弃

a|b


|在管道中分隔命令,因此cmd.exe将尝试将|之前的命令行部分通过管道传递给名为b的命令,并且调用很可能会中断,或者可能更糟,因为打算并执行不应执行的操作。


为了使这项工作有效,您需要在Python端将参数定义为'a^^^|b'(sic)。

请注意,a & b不会受到影响,因为嵌入式空白会在Python端触发双引号,并且在&中使用"..."是安全的。
引起类似问题的其他字符是& < >

关于batch-file - 完美地批量转发参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51759330/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com