没有 cmd/c 的 forfiles [英] forfiles without cmd /c

查看:22
本文介绍了没有 cmd/c 的 forfiles的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以运行 forfiles 命令cmd/c,如预期

<前>C:>forfiles/c "cmd/c ping/a"必须指定 IP 地址.

但是,如果我删除 cmd/c,它不再识别任何参数,只能识别基本命令

<前>C:>forfiles/c "ping/a"用法:ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS][-r 计数] [-s 计数] [[-j 主机列表] |[-k 主机列表]][-w 超时] [-R] [-S srcaddr] [-4] [-6] 目标名称

我是否必须使用 cmd/c,即使在 PATH 上使用外部命令?

解决方案

这是原始答案.请阅读下面的行以完整分析问题以及更好的解决方法

在命令及其参数之间放置两个空格

forfiles/c "ping/a"

<小时>

已编辑虽然发布的解决方案适用于 OP 问题,但它并不是一个完整的答案,因为在某些情况下此选项不起作用.

为什么?

我开始调试 forfiles 参数解析例程,认为问题在于解析和转换命令字符串以生成最终运行命令的方式.

不,它没有任何问题

问题的原因在于对CreateProcess API 函数的调用以及C 参数解析器的工作方式以及程序员通常如何处理参数.

forfiles 调用 API 为

CreateProcess('c:windowssystem32ping.exe','/a', ....)

也就是说,应用程序名称和它的参数.漂亮干净,但有问题,因为应用程序的第一个参数是 /a

问题出在哪里?在第一个论点中.几乎所有程序中通常的参数处理都假定程序的第一个参数是程序本身(至少是它的名称),即 argv[0] 是程序名称.

但是为了让它表现得那样,从 forfiles 调用 CreateProcess 应该是任何

CreateProcess('c:windowssystem32ping.exe','ping.exe/a', ....)CreateProcess(NULL, 'c:windowssystem32ping.exe/a', .... )

因为几乎每个用 C 编程的人(以及更多遵循相同约定的语言)都期望 argv[0](参数值表第一位置)将是程序名称和 argv[1](参数值表,第二个位置)将是第一个参数,因为在 forfiles 启动的进程中不是这种情况,第一个参数将被忽略,因为第一个实参将存储在 argv[0] 中,而不是 argv[1]

因此,正确的行为或失败将取决于被调用程序使用的解析器/词法分析器/标记器.

  • 他们中的一些人会将添加的空间视为附加参数,该参数将存储在 argv[0] 中(mingw/gcc 和 VC 中的标准分词器就是这样做的).

  • 其他人会去掉空格,取第一个非空白数据为argv[0](find的情况)

  • 分词器可以采用的任何其他行为.

一旦分词器结束其工作,程序将处理参数并选择其中之一

  • 忽略第一个参数,因为它假定程序名称在这个位置

  • 不对命令行中的内容做任何假设并确定参数.

所以,空间解决方案不是防弹解决方案(谢谢 dbenham)

如何解决?

由于问题是命令行参数中缺少程序名称,并且以下参数的位置不好,最好的选择似乎包括它(我们可以包括任何用作 argv[0],但正如大多数程序所期望的程序名称...)

forfiles/c "ping ping -a"forfiles/c "find find/c/v 0x220x22 @path"

I can run a forfiles command with cmd /c, as expected

C:>forfiles /c "cmd /c ping /a"
IP address must be specified.

However if I remove the cmd /c, it no longer recognizes any arguments, only the base command

C:>forfiles /c "ping /a"
Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
            [-r count] [-s count] [[-j host-list] | [-k host-list]]
            [-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name

Must I use cmd /c, even with external commands on the PATH?

解决方案

This is the original answer. Please read below the line for a complete analysis of the problem and a better way to solve it

Place two spaces between the command and its arguments

forfiles /c "ping  /a"


edited While the posted solution works for the OP question, it is not a complete answer, as there are some cases where this option does not work.

Why?

I started to debug the forfiles argument parsing routines thinking the problem is in the way the command string is parsed and converted to generate the final running command.

No, it works without any problem

The cause of the problem is in the call to the CreateProcess API function and the way the C argument parser works and how the programmers usually handle the arguments.

forfiles calls the API as

CreateProcess('c:windowssystem32ping.exe','/a', ....)

That is, the application name and the arguments to it. Nice and clean, but problematic, because the first argument to the application is /a

Where is the problem? In the first argument. The usual argument handling in almost any program assumes that the first argument to the program is the program itself (at least its name), that is, argv[0] is the program name.

But for it to behave that way, the call to CreateProcess from forfiles should be any of

CreateProcess('c:windowssystem32ping.exe','ping.exe /a', ....)
CreateProcess(NULL, 'c:windowssystem32ping.exe /a', .... )

As almost everyone programming in C (and in a lot more languages that follow the same convention) is expecting that argv[0] (arguments value table first position) will be the program name and argv[1] (arguments value table, second position) will be the first argument, and as this is not the case in forfiles started processes, the first argument will be ignored because the first real argument will be stored in argv[0], not argv[1]

So, correct behaviour or failure will depend on the parser/lexer/tokenizer used by the called program.

  • Some of them will see the added space as an aditional argument that will be stored inside argv[0] (the standard tokenizer in mingw/gcc and VC behave this way).

  • Others will remove the spaces and take the first non blank data as argv[0] (the case of find)

  • Any other behaviour you can think can be adopted by the tokenizer.

And once the tokenizer has ended its work, the program will handle the arguments and select one of

  • Ignore the first argument as it is assummed the program name is in this position

  • Make no assumptions on what will be found in the command line and identify the argument.

So, the space solution is not a bulletproof solution (thank you dbenham)

How to solve it?

As the problem is the absence of the program name in the command line argument, and the bad location of the following arguments, the best option seems to include it (well we can include anything to be used as argv[0], but as most programs expect the program name ...)

forfiles /c "ping ping -a"
forfiles /c "find find /c /v 0x220x22 @path"

这篇关于没有 cmd/c 的 forfiles的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆