【问题标题】:Terminate cat command immediately after using in C在 C 中使用后立即终止 cat 命令
【发布时间】:2016-09-01 16:51:44
【问题描述】:

所以我通过使用 echo 发送和 cat 接收来与设备通信。这是我的代码的 sn-p:

fp = popen("echo "xyz" > /dev/ttyACM0 | cat - /dev/ttyACM0", "r");
while (fgets(ret_val, sizeof(ret_val)-1, fp) != NULL)
{
    if (strcmp(ret_val, "response") == 0)
    {
       close(fp);
       return ret_val;
    }
}

好的,问题是,cat 似乎保持打开状态,因为当我在循环中运行此代码时,它第一次工作,然后在我调用 popen 的地方挂起。我假设猫是罪魁祸首是正确的吗?

有没有办法在我运行命令后立即终止 cat,所以我只是从我的设备获得响应?谢谢!

【问题讨论】:

  • 你为什么使用管道? echo 的输出会发送到设备,因此不会将任何内容写入管道。
  • cat 一直读到 EOF。如果设备在响应后没有发送 EOF,它应该如何知道它何时读取了整个响应?
  • 你为什么首先使用外部命令呢?只需在 C 程序中打开 /dev/ttyACM0
  • 就像@Barmar 所说,绝对没有理由使用popen 来写入/读取串行端口。您可以使用fopenfputsfgets。如果您需要更改串口的波特率或其他属性,请参见tcgetattr 手册页。
  • 其他小问题:1) -1sizeof(ret_val)-1 中不需要。 2)怀疑你想要"response\n"而不是"response"

标签: c cat tty


【解决方案1】:

在命令中:

echo "xyz" > /dev/ttyACM0 | cat - /dev/ttyACM0

TTY 设备通常在运营商存在或设置 CLOCAL 之前不会打开。猫可能正在等待开门。假设设备打开,那么猫会挂起等待读取字符,直到 (1) 它收到 EOF 字符,例如 control-D,或 (2) 载体丢失或 (3) 你杀死它。

这里的另一个问题是echo和cat之间的管道立即关闭,因为echo的输出被重定向到同一个TTY设备,重定向关闭管道。

通常,TTY 设备是凶猛的野兽,需要特殊处理才能获得正确的逻辑。也许您最好阅读 TTY 设备,尤其是:

man termios

如果你做的事情真的很简单,你可能会得到:

fp = popen("echo 'xyz' >/dev/ttyACM0 & (read x; echo \"$x\")");

请记住,echo 和 read 都可能会挂起等待载体,并且您最多只能从 popen 获得一行输出,而 read 可能会挂起等待 EOL 字符。

整个方法充满了问题。 TTY 设备需要精心呵护。你在黑暗中使用锤子。

【讨论】:

    【解决方案2】:

    没有简单的方法可以杀死 popen 启动的进程,因为没有 API 可以获取 pid —— 只有 pclose 一直等到它自己的帐户结束(你应该总是 使用pclose 而不是fclose 来关闭由popen 打开的FILE *。)

    相反,你最好不要使用popen——只需使用fopen并用fputs写你想要的:

    fp = fopen("/dev/ttyACM0", "r+");
    fputs("xyz\n", fp);   // include the newline explicitly
    fflush(fp);           // always flush after writing before reading
    while (fgets(ret_val, sizeof(ret_val)-1, fp) != NULL) {
               :
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 2014-08-02
      • 1970-01-01
      • 2023-01-04
      相关资源
      最近更新 更多