1

我最初编写了一个在我的 Linux 上运行命令的小型 c# 服务器。该应用程序很好地捕获了命令的标准输出并将它们发送回客户端。然后我在 Linux 机器上的 c# 环境就出现了问题。所以我决定用 c++ 重写应用程序,但遇到了重定向或 execl 函数的问题。我的第一次尝试可以让我的重定向工作,但随后我发出了 execl 调用。所以我做了一些搜索,发现了一些有效的代码,如何从 execl 命令中捕获输出. 我对代码做了一些小的修改来测试我对 execl 调用的处理,它不会重定向 avrdude 的标准输出。我确实更改了函数 cmd_quem 来处理应用程序名称和参数并为 execl 返回错误。主函数调用 cmd_quem 两次,例如命令,然后是我的命令。我也颠倒了这两个函数调用的顺序,每次我对 avrdude 的调用都不会重定向标准输出,但在 c# 中它起作用了。

我知道 avrdude 的路径是正确的。似乎这些论点也通过 excel 传递,我不知道为什么。输出应该是尝试读取进程而不是命令行选项。任何帮助,将不胜感激。

有什么想法或建议吗?

我的程序输出是

Starting RedirectPipesExe!
Usage: -c usbasp -p m8 [options]
Options:
  -p <partno>                Required. Specify AVR device.
  -b <baudrate>              Override RS-232 baud rate.
  -B <bitclock>              Specify JTAG/STK500v2 bit clock period (us).
  -C <config-file>           Specify location of configuration file.
  -c <programmer>            Specify programmer type.
  -D                         Disable auto erase for flash memory
  -i <delay>                 ISP Clock Delay [in microseconds]
  -P <port>                  Specify connection port.
  -F                         Override invalid signature check.
  -e                         Perform a chip erase.
  -O                         Perform RC oscillator calibration (see AVR053). 
  -U <memtype>:r|w|v:<filename>[:format]
                             Memory operation specification.
                             Multiple -U options are allowed, each request
                             is performed in the order specified.
  -n                         Do not write anything to the device.
  -V                         Do not verify.
  -u                         Disable safemode, default when running from a script.
  -s                         Silent safemode operation, will not ask you if
                             fuses should be changed back.
  -t                         Enter terminal mode.
  -E <exitspec>[,<exitspec>] List programmer exit specifications.
  -x <extended_param>        Pass <extended_param> to programmer.
  -y                         Count # erase cycles in EEPROM.
  -Y <number>                Initialize erase cycle # in EEPROM.
  -v                         Verbose output. -v -v for more.
  -q                         Quell progress output. -q -q for less.
  -l logfile                 Use logfile rather than stderr for diagnostics.
  -?                         Display this usage.

avrdude version 6.3-20171130, URL: <http://savannah.nongnu.org/projects/avrdude/>
No data received.
Child exit status = 0
Data from who command: pi       tty7         2020-07-22 19:25 (:0)

Child exit status = 0
End RedirectPipesExe!

我已经在 Gentoo 和树莓派盒子上测试了代码。覆盆子连接了一个函数式程序员,它是相同的输出。

int cmd_quem(const char *pApp, const char *pArgs) {
  int result;
  int pipefd[2];
  FILE *cmd_output;
  char buf[1024];
  int status;

  result = pipe(pipefd);
  if (result < 0) {
    perror("pipe");
    exit(-1);
  }

  result = fork();
  if (result < 0) {
    exit(-1);
  }

  if (result == 0) {
    dup2(pipefd[1], STDOUT_FILENO); /* Duplicate writing end to stdout */
    close(pipefd[0]);
    //close(pipefd[1]);

    //execl("/usr/bin/who", "who", NULL);
    int r = execl(pApp, pArgs, NULL);
    printf("Error returned by excel: %d\n", r);
    _exit(1);
  } 
  /* Parent process */
  close(pipefd[1]); /* Close writing end of pipe */

  cmd_output = fdopen(pipefd[0], "r");

  if (fgets(buf, sizeof buf, cmd_output)) {
    printf("Data from who command: %s\n", buf);
  } else {
    printf("No data received.\n");
  }

  wait(&status);
  printf("Child exit status = %d\n", status);

  return 0;
}

int main() {
  printf("Starting RedirectPipesExe!\n");
  cmd_quem("/usr/bin/avrdude", "-c usbasp -p m8");
  cmd_quem("/usr/bin/who", "who" ); 
  printf("End RedirectPipesExe!\n");
  return 0;
}
4

0 回答 0