У меня есть короткая программа c, которая выводит 3 строки, затем читает из stdin, и я хотел бы использовать сценарий оболочки для взаимодействия с ним следующим образом:
- чтение вывода c, строка за строкой
while read line; do ...; done <$out_
- сохранить вторую строку
if [ "$count" == 2 ]; then input=$line; fi
- отправить сохраненную строку обратно в программу
echo $input >$in_
Я использую именованные каналы в сценарии оболочки дляперенаправить вывод и ввод программы c:
./iotest >$out_ <$in_ &
но я не получаю ожидаемых результатов.
Проблема
После создания каналов out_
и in_
с mkfifo
, у меня есть петля while read
, но, похоже, это приводит к тупику. Ничего не читается, и сценарий оболочки застревает в команде чтения.
Я попытался добавить cat >$in_ &
перед запуском iotest
, как предлагалось здесь , чтобы открыть in_
для записина самом деле ничего не писать. Это разблокирует чтение, но не позволяет мне вводить в in_
(моя программа на c работает так, как будто я записал \ x00 в stdin, а команда echo $input >$in_
зависает).
Что япопробовал
Я прочитал здесь , который читает блоки, если нет записывающего, и без cat >$in_ &
У меня iotest
запись в out_
и read
чтение из негоЯ пытаюсь перенаправить in_
на iotest
, не записывая ничего с самого начала.
Но почему добавление команды cat приводит к сбою чтения программы на c, я не знаю. То же самое происходит, если я обменяю cat >$in_ &
на while true; do :; done >$in_&
или exec 3>$in_ &
(exec 3>$in_
, как предложено здесь , также зависает).
Код
Это мой код 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;
}
и это сценарий оболочки, который я тестировал:
$ 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_
I 'мы проверили это на 32-битном Debian и 64-битном Ubuntu, скомпилировали с помощью gcc и выполнили сценарий оболочки с помощью bash.
Результаты
без добавления команды 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.
Резюме
Поэтому мой вопрос: что не так с моим сценарием оболочки, и как я могу изменить его для чтения и записи вмоя программа c? Я не могу изменить сам код на c, но могу поиграться со скриптом оболочки.
Спасибо за любую помощь!