我试图通过C程序运行BASH命令,但我正在努力使用execv函数。我真的不知道如何编写该函数的第一个参数。我尝试使用strcat函数追加字符串" / bin /"使用argv选项卡的第一个元素,这是我在运行程序时编写的命令,但它不起作用。我得到了一个"分段错误"。而不是使用我尝试使用strdup的strcat函数,但我不知道如何正确使用它。
任何帮助将不胜感激。我的节目如下。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[], char *envp[]){
char *tab[] = {argv[1],NULL};
if(execve(strcat("/bin/",argv[1]), tab, envp)==-1)
{
perror("execve");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
答案 0 :(得分:1)
要从C程序运行shell命令,您应该使用system(3)。
如果你想获得它的标准输出(或给它的标准输入,但不是两者),请使用popen(3)(不要忘记pclose
这样的流。)
使用的shell(system
和popen
)并不完全是bash
,而是标准POSIX /bin/sh
(与bash
非常相似,但有一些限制)
要构建该shell命令(但要注意其中的code injections),您可以使用常见的字符串函数,例如snprintf和asprintf。
请注意execve(2)在成功时不会返回,并且它不会通过shell运行命令,而是直接执行可执行程序。实际上Unix shells(例如bash
或/bin/sh
)经常使用fork(2),execve(2),waitpid(2)并正在实施globbing 。 BTW system
&amp; popen
也在fork
上使用execve
和/bin/sh -c
。
strcat("/bin/",argv[1])
非常错误,strcat
的第一个参数是覆盖的目标缓冲区(因此不能是字符串文字),并且不要检查buffer overflow。
您可能想要编码:
char progbuf[80];
int ln = snprintf(progbuf, sizeof(progbuf), "/bin/%s", argv[1]);
您应该稍后查看ln<(int)sizeof(progbuf)
我尝试使用strdup,但我不知道如何使用它。
在使用任何功能之前,您需要仔细阅读其文档,例如strdup(3)(或在终端中输入man strdup
)。
答案 1 :(得分:1)
关于:
if(execve(strcat("/bin/",argv[1]), tab, envp)==-1)
这不起作用,
建议:
#include <stdio.h> // perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <sys/types.h>
#include <sys/wait.h> // waitpid()
#include <unistd.h> // fork(), execvp()
#include <string.h> // strlen(), strcpy(), strcat()
int main( int argc, char *argv[], char *env[] )
{
(void)argc;
char *tab[] = { argv[1], NULL };
char string[strlen(argv[1]) + strlen( "/bin/" ) +1 ];
strcpy( string, "/bin/" );
strcat( string, argv[1] );
int status;
pid_t pid = fork();
switch( pid )
{
case -1: // fork failed
perror( "fork failed" );
exit( EXIT_FAILURE );
break;
case 0: // child process
execve( string, tab, env ); // does not return unless an error
perror("execve failed");
exit( EXIT_FAILURE );
break;
default:
waitpid( pid, &status, 0 );
break;
}
}
警告:建议的代码只隐藏参数:argc
而不是正确检查它以确保命令行确实包含参数。
警告:main的参数:env[]
不可移植,不应使用。建议使用:
extern char *environ[];
答案 2 :(得分:0)
Melpomene是对的 - 你不能那样使用strcat
。在C中,您无法返回字符串。你要做的是将一个内存地址(指针)作为strcat
中的第一个参数传递,然后strcat
修改它所指向的内存,以便它还包含strcat
的第二个参数。这是一个你将在C中反复重复的过程,所以你应该理解它。此外,strcat
看起来并不安全,我打赌有一个strcatn
函数或类似的东西。
答案 3 :(得分:0)
我终于找到了一种方法来做我想做的事情。感谢你们所有人的帮助和帮助。建议!这是解决方案!
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[], char *envp[]){
char *tab[] = {argv[1],argv[2],NULL};
char test[20] = "/bin/";
if(execve(strcat(test,argv[1]), tab, envp)==-1)
{
perror("execve");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}