我有一个简短的 c 程序,输出 3 行然后从标准输入读取,我想使用 shell 脚本与其交互,如下所示:
- 逐行读取 c 输出
while read line; do ...; done <$out_
- 保存第二行
if [ "$count" == 2 ]; then input=$line; fi
- 将保存的行发送回程序
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_
的阅读器,因此subshell 能够打开两个 fifos 并执行 iotest
。至于您看到的行为,这是您的 iotest.c 中的错误。打印 read
返回的值(到 stderr!),包括 read
的声明,并尝试使用 != -1
而不是 > -1
.
关于c - 从 shell 脚本读取然后写入 c 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58283426/