[英]Running BASH command via C program
我正在嘗試通過C程序運行BASH命令,但是我正在為函數execv苦苦掙扎。 我真的不知道如何編寫該函數的第一個參數。 我嘗試使用strcat函數將字符串“ / bin /”附加到argv選項卡的第一個元素上,這是我在運行程序時編寫的命令,但它不起作用。 我收到“細分錯誤”。 我沒有使用strcat函數,而是嘗試使用strdup,但是我不知道如何正確使用它。
任何幫助,將不勝感激。 我的程序在下面。
#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;
}
要從C程序運行shell命令,應使用system(3) 。 如果要獲取其stdout(或提供其stdin,但不能同時提供兩者),請使用popen(3) (不要忘記pclose
此類流)。
( system
和popen
)shell並非完全是bash
而是標准的POSIX /bin/sh
(與bash
相似,但有一些限制)。
要構建該shell命令(但要注意其中的代碼注入 ),可以使用常見的字符串函數,例如snprintf和asprintf 。
請注意, execve(2)成功執行后不會返回,並且不會通過外殼程序運行命令,而是直接運行可執行程序。 實際上, Unix shell (例如bash
或/bin/sh
)經常使用fork(2) , execve(2) , waitpid(2)並實現globbing 。 BTW system
和popen
還在/bin/sh -c
上使用fork
和execve
。
strcat("/bin/",argv[1])
完全錯誤, strcat
的第一個參數是被覆蓋的目標緩沖區(因此不能是字符串文字),並且您不檢查緩沖區溢出 。
您可能要編寫代碼:
char progbuf[80];
int ln = snprintf(progbuf, sizeof(progbuf), "/bin/%s", argv[1]);
然后您應該檢查ln<(int)sizeof(progbuf)
順便說一句,您的程序在改進時不會使用Bash。 它直接執行一些命令。
我嘗試過使用strdup,但是我不知道如何正確使用它。
在使用任何功能之前,您需要仔細閱讀其文檔,例如strdup(3) (或在終端中輸入man strdup
)。
關於:
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[];
Melpomene是對的-您不能那樣使用strcat
。 在C語言中,您無法返回字符串。 您要做的是將內存地址(指針)作為strcat
的第一個參數傳遞,然后strcat
修改它所指向的內存,以便它還包含strcat
的第二個參數。 您將在C中一遍又一遍地重復此過程,因此您應該了解它。 另外,該strcat
看起來並不安全,我敢打賭有一個strcatn
函數或類似的東西。
終於,我終於找到了一種方法來做自己想做的事情。 感謝大家的幫助和建議! 這是解決方案!
#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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.