exec()是C语言中的任意命令
比如在C语言中,我想对任何字符串命令调用exec()是C语言中的任意命令,c,linux,shell,execvp,C,Linux,Shell,Execvp,比如在C语言中,我想对任何字符串命令调用execvp()。命令可以是: char command[] = "ls -l"; char command[] = "rm *.txt"; char command[] = "cat makefile"; 我想将此命令变量放入execvp()中。因此exec()风味函数可以使用任意命令运行 我该怎么做?谢谢 注意:system()是不允许的。如果必须调用execvp(),则需要将这些字符串拆分为可执行名称和参数数组(第一个是程序的“名称”,最后一个是空
execvp()
。命令可以是:
char command[] = "ls -l";
char command[] = "rm *.txt";
char command[] = "cat makefile";
我想将此命令变量放入execvp()
中。因此exec()
风味函数可以使用任意命令运行
我该怎么做?谢谢
注意:system()
是不允许的。如果必须调用execvp()
,则需要将这些字符串拆分为可执行名称和参数数组(第一个是程序的“名称”,最后一个是空指针)
这意味着:
char cmd1[] = "ls"; char *args1[] = {"ls", "-l", NULL};
char cmd1[] = "rm"; char *args1[] = {"rm", "*.txt", NULL}; // but see
// globbing below.
char cmd1[] = "cat"; char *args1[] = {"cat", "makefile", NULL};
这是一个非常重要的练习,特别是如果您想允许引用、全局搜索、转义等
引用意味着您必须小心使用以下命令:
rm "file with spaces.txt"
因为您不能简单地打断空格,您必须像shell一样解释命令中的项。简单地打断空格会给您一个命令,上面的字符串有三个参数,而不是正确的参数
通过globbing,我的意思是您几乎肯定会遇到类似*.txt
的问题,因为它通常是扩展这些参数的shell。将其直接传递到execvp()
将产生一个单独的参数*.txt
,而不是许多匹配当前目录中所有文本文件的参数
引用意味着您必须处理以下事项:
ls -l "file with spaces and \" quote in it"
这将使解析器更加复杂
别误会,这是可以做到的,但使用system()
可能会更容易
如果您仍在考虑采用execvp()
路线,您必须:
- 将字符串拆分为单独的标记(相当困难,因为您必须处理引号和转义)
- glob所有参数,这意味着那些带有通配符的参数(只有那些没有通过引号内的形式转义或保护的参数)被扩展为多个参数
- 构造参数数组,命令在前面,NULL在结尾
- 调用
,参数为该数组中的第一个元素和数组的地址execvp()
exec
函数系列不像system
那样使用单个字符串命令行。相反,它使用类似于argv的字符串数组:
char *command = "/path/to/command";
char *arguments[] = { "command", "first argument", "second argument", NULL };
execvp(command, arguments);
请注意,arguments
数组中的第一个条目是命令本身,数组以NULL
终止
您是否查看了手册页面?要使用任何execve样式的函数,您需要自己解析命令行并构建一个argv向量。这些函数采用char**,其中最后一个元素为null——您需要为所有这些分配足够的内存。那么您的execve风格调用应该可以工作
(P.S.你没有提到任何关于叉子…)
为了得到像“*”“>”之类的东西,你需要做的是让shell解析命令。所以考虑一下:
/bin/sh -c 'rm *.txt'
这应该会让您朝着正确的方向前进。:)为什么不允许使用
system()
“大概是因为他在上操作系统课,他们不允许吗?是的,作业中最后一件事我想不出来。显然,这是作业。”。以后请这样标记。虽然使用/bin/sh
很方便,但他的作业规则明确规定“nosystem(3)
”,这实际上与no/bin/sh
/相同。很抱歉,麻烦了,我不得不问我是否可以使用/bin/sh
。如果我使用/bin/sh
,我可以做char*const parmList[]={“sh”,“ls-l”,NULL};execvp(“/bin/sh”,parmList)代码>但它似乎不正确。语法错误?应该是char*const parmList[]={“sh”、“-c”、“ls-l”、NULL};execvp(“/bin/sh”,parmList)代码>是的,我的代码中有fork。我想我必须解析字符串。谢谢。是的,很遗憾。这就是shell所做的,真的,因为要处理的事情太多了是的,你说的是char*command=“/path/to/command”代码>我可以只做char*command=“command”
在所有可能的情况下?这是否意味着如果我实现一个以null结尾的字符串数组{“rm”、“*foo”、“*bar”}
,则execvp
应该执行“*foo”
和“*bar”
的所有匹配组合?比如说,组合应该是rm*foo[0]*foo[n-1]*bar[0]*bar[n-1]
。或者,它不是嵌套循环中的execvp
,而是包含扩展(全局)参数的单个命令。比如说,{rm,afoo,bfoo,abar,…,NULL}
。