问题描述
如果我想输入路径中需要空格的命令,该如何在c ++中使用system()函数?示例代码:
How do I use the system() function in c++ if I want to enter a command that needs a path when my path has spaces in it?Example code:
#include <iostream>
int main()
{
std::string command = "ls -la /home/testuser/this is a folder/test/";
std::cout << "Click enter to execute command..." << std::endl;
getchar();
std::system(command.c_str());
return 0;
}
这可能行不通,因为外壳程序需要在空格前加退格键.不幸的是,这也行不通:
This doesn't work supposedly because the shell needs backspaces in front of a space.Unfortunately this doesn't work too:
std::string command = "ls -la /home/testuser/this\b is\b a\b folder/test/";
有什么主意我在做错什么,或者我怎么做得更好?谢谢.
Any idea what I'm doing wrong or how I could do it better? Thanks.
推荐答案
问问自己:如何从shell提示符下自己执行此命令?
Ask yourself: how would you execute this command, yourself, from a shell prompt?
$ ls -la /home/testuser/this is a folder/test/
这当然不会以您的程序失败的相同原因起作用.相反,正如每一篇有关Shell脚本的入门知识所教您的那样,您需要引用以下参数:
This, of course, will not work for the same reason your program fails. Instead, as every primer on shell scripting teaches you, you need to quote the parameter:
$ ls -la "/home/testuser/this is a folder/test/"
这将起作用,并且您使用system()
的方式完全相同:
That will work, and you use system()
in exactly the same way:
std::string command = "ls -la \"/home/testuser/this is a folder/test/\"";
但是更好的是首先不使用system()
.出于所有实际目的,所有system()
都是fork()
,在子进程中后跟exec()
,父进程wait()
用于终止子进程.
But what's even better is not using system()
in the first place. All the system()
is, for all practical purposes, is a fork()
, followed by exec()
in the child process, with the parent process wait()
ing for the child process's termination.
问题在于子进程exec()
是系统外壳,该外壳根据其规则解析命令.这包括直接通过外壳执行命令时发生的所有正常情况:文件名扩展,遍历和其他情况.
The problem is that the child process exec()
the system shell, which parses the command according to its rules. This includes all the normal things that occur when executing the command via the shell directly: filename expansion, globbing, and other things.
如果传递给exec()
的字符串包含任何特殊的shell字符,它们将由shell解释.在这种情况下,您有意使用此命令正确解析命令字符串,以便将正确的参数传递给/bin/ls
.
If the string that gets passed to exec()
includes any special shell characters, they'll be interpreted by the shell. In this case, you're intentionally using this to correctly parse the command string, in order to pass the correct arguments to /bin/ls
.
在执行特定的固定命令时,这很好.但是,当实际命令有所不同,或包含外部指定的参数时,您有责任正确处理任何外壳通配符,以得到预期的结果.随之而来的是Hillarity.在这种情况下,您会发现使用fork()
和exec()
自己将产生确定性更高,更可靠的结果,您可以完全控制传递给正在执行的命令的所有参数,而不必依赖于系统外壳程序为您做到这一点.
When executing a specific, fixed command, this is fine. But when the actual command varies, or contains externally-specified parameters, it is your responsibility to correctly handle any shell wildcard characters in order to get your intended result. Hillarity ensues, otherwise. In that situation, you will find that using fork()
and exec()
yourself will produce far more deterministic, and reliable results, where you are in complete control of all arguments that get passed to the command being executed, instead of relying on the system shell to do it for you.
这篇关于带空格的C ++ system()命令路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!