c - 从 shell 脚本读取然后写入 c 程序

标签 c linux shell deadlock named-pipes

我有一个简短的 c 程序,输出 3 行然后从标准输入读取,我想使用 shell 脚本与其交互,如下所示:

  1. 逐行读取 c 输出 while read line; do ...; done <$out_
  2. 保存第二行if [ "$count" == 2 ]; then input=$line; fi
  3. 将保存的行发送回程序 echo $input >$in_

我在 shell 脚本中使用命名管道来重定向 c 程序的输出和输入:

./iotest >$out_ <$in_ &

但我没有得到预期的结果。

问题

创建管道后 out_in_mkfifo , 我有一个 while read循环,但它似乎会导致死锁。未读取任何内容,shell 脚本卡在读取命令上。

我尝试添加 cat >$in_ &发射前iotest , 提议 here , 打开 in_用于写作而不实际写任何东西。这会取消阻止读取,但不允许我输入 in_ (我的 c 程序就像我将\x00 写入标准输入一样,echo $input >$in_ 命令挂起)。

我尝试过的

我读过 here如果没有写入器,则读取 block ,并且没有 cat >$in_ &我有iotest写信给 out_ , 和 read从中读取,我正在尝试重定向 in_iotest从一开始就没有写任何东西。

但是为什么加了cat命令会导致c程序读取失败,我就不知道了。如果我交换 cat >$in_ & 也会发生同样的情况与 while true; do :; done >$in_&exec 3>$in_ & ( exec 3>$in_ ,建议 here ,也挂起)。

代码

这是我的 C 代码:

$ cat iotest.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main (int argc, char* argv[])
{
    char A[9] = "";
    printf("hello. please send me the following line:\n");
    printf("input me\n");
    printf("now send me the line:\n");
    int ret = read(0,A,8);
    fprintf(stderr,"read returned %i\n",ret);
    if(ret != -1) {
        printf("You sent: %s\n", A);
        if (strcmp(A,"input me") == 0) {
            printf("correct!\n");
        } else {
            printf("wrong line.\n");
        }
    } else {
        printf("read failed.\n");
    }
    return 0;
}

这是我测试过的 shell 脚本:

$ cat runiotest.sh 
#!/bin/bash

in_=/tmp/testpipein
out_=/tmp/testpipeout

mkfifo $in_
mkfifo $out_
count=0
input=""

./iotest >$out_ <$in_ &
while read line
do
    count=$((count+1))
    echo "line number $count:"
    echo $line
    if [ "$count" == 2 ]
    then
        input=$line
    fi
    if [ "$count" == 3 ]
    then
        echo "$input" >$in_
    fi
done < $out_

rm -f $in_
rm -f $out_

我已经在 32 位 debian 和 64 位 ubuntu 上测试过,使用 gcc 编译,并使用 bash 执行 shell 脚本。

结果

没有添加 cat 命令:

$ /bin/bash/ ./runiotest.sh
(hangs)

添加了 cat >$in_ & :

$ /bin/bash ./runiotest.sh
read returned 0
line number 1:
hello. please send me the following line:
line number 2:
input me
line number 3:
now send me the line:
line number 4:
You sent:
line number 5:
wrong line.

总结

所以我的问题是:我的 shell 脚本有什么问题,我如何修改它以读取然后写入我的 c 程序?我无法更改 C 代码本身,但可以摆弄 shell 脚本。

感谢您的帮助!

最佳答案

考虑:

./iotest >$out_ <$in_ &
while read line; do ...; done < $out_

在这里,子 shell 尝试打开 $out_ 进行写入,打开 $in_ 进行读取,它甚至不会执行 iotest 直到这两个 fifos 都打开。如果没有你添加的 cat,子 shell 将无法打开 $in_ 直到有一些编写器,所以 iotest 甚至永远不会开始执行。当您添加 cat 时,子 shell 能够打开 $in_,主 shell 充当 $out_ 的阅读器,因此subshel​​l 能够打开两个 fifos 并执行 iotest。至于您看到的行为,这是您的 iotest.c 中的错误。打印 read 返回的值(到 stderr!),包括 read 的声明,并尝试使用 != -1 而不是 > -1.

关于c - 从 shell 脚本读取然后写入 c 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58283426/

相关文章:

linux - 当实用程序 w3m 的进程运行时,脚本有时会阻塞

linux - 如何将旧文件移动到另一个文件夹

android - FFmpeg 安卓构建

python - 按列连接多个文件的最快方法 - Python

linux - 使用 shell 脚本检查文件是否为 jpeg 格式

c - 在C中的不同文件中获取标准输出和错误输出

c - 在C混淆中将二维数组传递给函数

c - 如何将套接字 recv(,,,) 用于不确定的响应长度

c - 如何从字符串初始化字符数组,其间具有特殊的十六进制值

linux - 为什么/proc/kcore 文件这么大?