考虑以下 Windows 10 上的 CMD session ,以 #
开头的行是注释:
# We have this simple program
D:\testdir>type prg.c
#include <stdio.h>
int main() {
printf("Hello prg");
return 0;
}
# This is "realgcc.exe (Rev2, Built by MSYS2 project) 6.2.0"
D:\testdir>gcc prg.c -o prg
D:\testdir>prg.exe
Hello prg
D:\testdir>md dir
D:\testdir>cd dir
D:\testdir\dir>..\prg.exe
Hello prg
# This does not work however
D:\testdir\dir>../prg.exe
'..' is not recognized as an internal or external command,
operable program or batch file.
# But this does
D:\testdir\dir>"../prg.exe"
Hello prg
# Now we want to call the same program, from the same directory,
# but from C instead, so we create this file
D:\testdir\dir>type call.c
#include <stdlib.h>
int main() {
system("..\\prg.exe");
return 0;
}
D:\testdir\dir>gcc call.c -o call
D:\testdir\dir>call.exe
Hello prg
# Now to the question: If we modify the system function call
# to the following -- why doesn't it work?
D:\testdir\dir>type call.c
#include <stdlib.h>
int main() {
system("\"../prg.exe\"");
return 0;
}
D:\testdir\dir>gcc call.c -o call
D:\testdir\dir>call.exe
'..' is not recognized as an internal or external command,
operable program or batch file.
显然调用 system
与在 CMD session 中交互式运行命令不同?引号是否出于某种原因被删除?是否有另一种语法可用于使用包含 /
而不是 \
作为分隔符的相对路径来调用其他目录中的可执行文件?
(我在尝试让 Cygwin 程序和普通的 Windows 程序相互对话时注意到这一点。)
编辑:显然,这行得通:
#include <stdlib.h>
int main() {
system("\"\"../prg.exe\"\"");
return 0;
}
可能相关,在CMD中,
cmd /c ""../prg.exe""
有效,而这个无效
cmd /c "../prg.exe"
所以似乎在 system
调用中出于某种原因需要一些额外的引号?
最佳答案
感谢您提供所有有用的评论,我现在明白发生了什么。在问这个问题时,我没有考虑命令(即 system
的参数)实际上是如何传递给“命令解释器”的,这是理解为什么外部引号消失的关键.
在 Windows 上,调用 system("command")
本质上与使用参数 /c< 生成一个新的
和 cmd.exe
进程是一样的命令
。 (在 Linux and similar OSes 上,我们将与 sh -c command
等价。)
然而,这里的问题是,在大多数情况下,当通过 /c
标志传递命令时,Windows 的 CMD 将去除第一个和最后一个引号字符。这在 cmd/?
给出的文档中有说明:
[...]
If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:
1. If all of the following conditions are met, then quote characters
on the command line are preserved:
- no /S switch
- exactly two quote characters
- no special characters between the two quote characters,
where special is one of: &<>()@^|
- there are one or more whitespace characters between the
two quote characters
- the string between the two quote characters is the name
of an executable file.
2. Otherwise, old behavior is to see if the first character is
a quote character and if so, strip the leading character and
remove the last quote character on the command line, preserving
any text after the last quote character.
[...]
关于c -/vs.\in CMD 和 C 系统函数中可执行文件的相对路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47470077/