在CGI脚本中使用popen调用系统cmd

时间:2016-06-29 14:19:19

标签: c linux cmd cgi

尝试执行包含CGI script的{​​{1}}来执行cmd。即使popen()返回有效指针但它无法执行所需的操作。

命令我想执行popenlsblk

insmod

HTML内容:

void cmd_execute(char *cmd, char *buff, int len)
{
    FILE *f = popen(cmd,"r");
    if (NULL == f){
        printf("<p> popen failed");
        return;
    }
    fread(buff,len,1,f);
    pclose(f);

    printf("<p> buff: %s",buff);
}

当我为<!DOCTYPE html> <html> <body bgcolor="#4a7d49"> <form ACTION="http://localhost/cgi-bin/run.cgi" METHOD="POST" target="display_page"> <input type="submit" value="List Drivers"></form> <br /><br /> </body> </html> cmd尝试相同时,我得到了理想的结果。但是其他命令都失败了。我在ls尝试这个。我尝试使用 cmd参数中的rhel6.4su -s更改权限,但它没有帮助。我收到的错误就像 无法打开会话 。如果有更好的方法可以让我知道。

2 个答案:

答案 0 :(得分:0)

修改发布的代码后:

  1. 所以它干净地编译
  2. 并添加错误检查
  3. 编辑:将fclose()更改为pclose()
  4. 编辑:已添加对wait()的调用以完成子流程
  5. 结果如下:

    #include <stdio.h>   // printf(), popen(), pclose(), fread()
    #include <stdlib.h>  // exit(), EXIT_FAILURE
    
    // EDIT: added next two header files for 'wait()'
    #include <sys/types.h>
    #include <sys/wait.h>
    
    
    
    
    void cmd_execute(char *cmd, char *buff, size_t len)
    {
        FILE *f = popen(cmd,"r");
        if (NULL == f)
        { // then popen failed
            perror( "popen failed" );
            exit( EXIT_FAILURE );
        }
    
        size_t byteCount = fread(buff,len,1,f);
        if( 0 >= byteCount )
        { // then fread failed
            perror( "fread failed" );
            pclose(f);
            wait( NULL );
            exit( EXIT_FAILURE );
        }
    
        pclose(f);
        wait( NULL );
    
        printf("<p> buff: %s\n<\\p>",buff);
    } // end function: cmd_execute
    
    
    int main( void )
    {
        char *command= "lsblk";
        char buffer[100];
    
        cmd_execute( command, buffer, 100 );
    } // end function: main
    

    然后我在我的系统上运行它:

    ubuntu linux 14.04

    哪个输出:

    <p> buff: NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
    sda      8:0    0 931.5G  0 disk 
    ├─sda1   8:1    0 
    <\p>
    

    注意:输出的第三行确实包含一些非ascii&#39;可能会导致浏览器出现问题的字符。

    您可能希望在每次调用printf()后添加对perror()的调用,以在浏览器窗口中显示错误消息。

答案 1 :(得分:0)

Su(1)是一个必须以交互方式运行的命令。它会打开/dev/tty以便能够要求输入密码,并且当您在没有控制终端的会话中运行它时(所有守护程序会话都是非终端的)open(2) /dev/tty失败(有那个确切的错误)

解决方案是使用其他方法将密码传递给su(1)。阅读其文档,看看是否有另一种方法可以传递正确的密码。或者命令它不要求密码。

顺便说一句,与此无关,但popen(3) 必须使用pclose(3) 而不是fclose(3)关闭。这是因为pclose杀死了孩子并等待它终止,而不是让它在通信通道关闭的情况下运行。

最后一件事:我不知道你的容器的情况,但有些不允许你产生新的进程,所以要小心。我认为这不是你的情况。