用c语言编写bash应用程序的STDIN

用c语言编写bash应用程序的STDIN,c,linux,bash,stdin,C,Linux,Bash,Stdin,我想打开一个bash应用程序(prog1)并用C程序向该应用程序发送命令。 我尝试并编写了以下代码 #include <stdlib.h> #include <stdio.h> #include <unistd.h> int main() { FILE * fp; char message[10] = "command1\n"; fp = popen("sudo prog1","r"); write(STDIN_FILENO,

我想打开一个bash应用程序(prog1)并用C程序向该应用程序发送命令。 我尝试并编写了以下代码

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    FILE * fp;
    char message[10] = "command1\n";
    fp = popen("sudo prog1","r");
    write(STDIN_FILENO, message, 10);
    pclose(fp);
    execlp("sudo prog1", "sudo prog1", "-l", NULL);
    return 0;
}
但我希望是这样

Linux:~$ ./ prog 2 // running the code
prog1-> command    // open "prog1" and write command (instead of getting it from user)
它要么在退出prog1之后写入,要么在开始prog1之前写入。打开应用程序prog1后,请告诉我如何在prog1中编写“命令”。多谢各位

注:如果我

fp = popen("sudo prog1","w");  //to write
它抛出以下错误
tcgetattr:ioctl不适合设备

您的主要错误是认为popen()以某种方式将您的子进程与STDIN\u文件号关联起来。没有。STDIN_FILENO与您的“sudo prog1”子项不关联。您必须创建一个管道,将描述符复制到stdin/stdout,然后使用fork+exec来完成。但是您使用了popen(),所以也不要这样做

相反,你应该从fp写作和阅读

比如:

  fprintf(fp, message);
  fgets(response, 100, fp);
因为fprintf()是缓冲的,所以应该在行的末尾使用\n或fflush()

此外,在已经调用popen()的情况下,在末尾使用exec/execlp也没有意义。看起来您可能混合了您通过示例看到的两种方法

popen()实际上是(pipe、dup stdin/stdout/stderr、fork、execl)的组合,用于将子进程重定向到连接到父进程的文件流。因此,除非需要与popen()不同的语义,否则无需重新实现

从技术上讲,您正在实现“expect”功能,因此您可能希望查看expect,或者使用不同语言的expect模块。Expect包含在Linux发行版中,但通常是可选的

更不用说,Perl已经有了Sudo模块


您的主要错误是认为popen()以某种方式将您的子进程与stdinu文件号关联起来。没有。STDIN_FILENO与您的“sudo prog1”子项不关联。您必须创建一个管道,将描述符复制到stdin/stdout,然后使用fork+exec来完成。但是您使用了popen(),所以也不要这样做

相反,你应该从fp写作和阅读

比如:

  fprintf(fp, message);
  fgets(response, 100, fp);
因为fprintf()是缓冲的,所以应该在行的末尾使用\n或fflush()

此外,在已经调用popen()的情况下,在末尾使用exec/execlp也没有意义。看起来您可能混合了您通过示例看到的两种方法

popen()实际上是(pipe、dup stdin/stdout/stderr、fork、execl)的组合,用于将子进程重定向到连接到父进程的文件流。因此,除非需要与popen()不同的语义,否则无需重新实现

从技术上讲,您正在实现“expect”功能,因此您可能希望查看expect,或者使用不同语言的expect模块。Expect包含在Linux发行版中,但通常是可选的

更不用说,Perl已经有了Sudo模块


您的主要错误是认为popen()以某种方式将您的子进程与stdinu文件号关联起来。没有。STDIN_FILENO与您的“sudo prog1”子项不关联。您必须创建一个管道,将描述符复制到stdin/stdout,然后使用fork+exec来完成。但是您使用了popen(),所以也不要这样做

相反,你应该从fp写作和阅读

比如:

  fprintf(fp, message);
  fgets(response, 100, fp);
因为fprintf()是缓冲的,所以应该在行的末尾使用\n或fflush()

此外,在已经调用popen()的情况下,在末尾使用exec/execlp也没有意义。看起来您可能混合了您通过示例看到的两种方法

popen()实际上是(pipe、dup stdin/stdout/stderr、fork、execl)的组合,用于将子进程重定向到连接到父进程的文件流。因此,除非需要与popen()不同的语义,否则无需重新实现

从技术上讲,您正在实现“expect”功能,因此您可能希望查看expect,或者使用不同语言的expect模块。Expect包含在Linux发行版中,但通常是可选的

更不用说,Perl已经有了Sudo模块


您的主要错误是认为popen()以某种方式将您的子进程与stdinu文件号关联起来。没有。STDIN_FILENO与您的“sudo prog1”子项不关联。您必须创建一个管道,将描述符复制到stdin/stdout,然后使用fork+exec来完成。但是您使用了popen(),所以也不要这样做

相反,你应该从fp写作和阅读

比如:

  fprintf(fp, message);
  fgets(response, 100, fp);
因为fprintf()是缓冲的,所以应该在行的末尾使用\n或fflush()

此外,在已经调用popen()的情况下,在末尾使用exec/execlp也没有意义。看起来您可能混合了您通过示例看到的两种方法

popen()实际上是(pipe、dup stdin/stdout/stderr、fork、execl)的组合,用于将子进程重定向到连接到父进程的文件流。因此,除非需要与popen()不同的语义,否则无需重新实现

从技术上讲,您正在实现“expect”功能,因此您可能希望查看expect,或者使用不同语言的expect模块。Expect包含在Linux发行版中,但通常是可选的

更不用说,Perl已经有了Sudo模块


将您启动的程序写入STDIN,而不是写入您自己的程序,怎么样?应该这样做。此外,我认为你的
execlp
是一个孤儿,除了你给它提供了糟糕的论据。或者你有一个名为“sudo prog1”的程序吗?我有一个名为“prog1”的程序,但如果我没有包含“sudo”,它会显示“无法打开文件:权限被拒绝”,这是一个权限问题,与你问的问题无关。在开始作为普通用户工作之前,您是否将prog1创建为root用户?sudo为您提供命令作用域的根priv。你可能不知道