簡體   English   中英

通過C程序運行BASH命令

[英]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此類流)。

systempopen )shell並非完全是bash而是標准的POSIX /bin/sh (與bash相似,但有一些限制)。

要構建該shell命令(但要注意其中的代碼注入 ),可以使用常見的字符串函數,例如snprintfasprintf

請注意, execve(2)成功執行后不會返回,並且不會通過外殼程序運行命令,而是直接運行可執行程序。 實際上, Unix shell (例如bash/bin/sh )經常使用fork(2)execve(2)waitpid(2)並實現globbing BTW systempopen還在/bin/sh -c上使用forkexecve

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)  

這是行不通的,

  1. 文字“ / bin /”位於只讀存儲器中,因此無法更改(需要足夠大的char緩沖區來容納完整字符串,類似於`char string [100] =“ / bin /”;

建議:

#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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM