out="$katalog/out" # wyjscie
fifo="$katalog/fifo" # wejscie
mkfifo $fifo
touch $out
[...] #k
./a.out <$fifo >$out & pid=$!
[...] # get input line by line loop start
echo "$liniain" >> $fifo
[...] # loop end
이 작업을 시도했지만 프로그램 스크립트의 첫 번째 입력 줄이 중지된 후 응답이 없습니다.
전체 스크립트
#!/bin/bash
#Debuger programow w c ++
katalog="/tmp/debuger$$"
mkdir $katalog # katalog tymczasowy z danymi
out="$katalog/out" # wyjcie
fifo="$katalog/fifo" # wejscie
mkfifo $fifo # nawet powstalo (potok nazwany)
touch $out
if [ -n $0 ] ; then echo "podaj -h"
fi
while getopts hvar opt ; do
case $opt in
h) echo "Script prowadzi za raczke -r reset ustawien -a autor ";;
v) echo "--wersja---";;
a) echo "Jakub Staniszewski";;
r) rm ./debug.cfg;;
*) echo "nie rozumiem";;
esac
done
if [ ! -e ./debug.cfg ] ; then
dialog --title "PLIKI IN" --fselect ./ 10 40 2>$katalog/dial
pliki_in=$(<$katalog/dial)
dialog --title "PLIKI OUT" --fselect ./ 10 40 2>$katalog/dial
pliki_out=$(<$katalog/dial)
dialog --title "CO SKOMPILOWAC" --fselect ./ 10 40 2>$katalog/dial
plik_compile=$(<$katalog/dial)
dialog --title "Opcje_kompilatora" --inputbox "Podaj Nazwe pliku wykonywalnego" 8 40 "a.out" 2> $katalog/dial
program=$(<$katalog/dial)
dialog --title "Opcje_kompilatora" --inputbox "Podaj opcje cd" 8 40 "" 2> $katalog/dial
flagi=$(<$katalog/dial)
dialog --title "Polecenie do debugowania" --inputbox "Podaj polecenie do debugowania" 8 40 "debug" 2> $katalog/dial
debugpolecenie=$(<$katalog/dial)
echo "pliki_in=$pliki_in" > ./debug.cfg
echo "pliki_out=$pliki_out" >> ./debug.cfg
echo "plik_compile=$plik_compile" >> ./debug.cfg
echo "program=$program" >> ./debug.cfg
echo "flagi=$flagi" >> ./debug.cfg
echo "debugpolecenie=$debugpolecenie" >> ./debug.cfg
fi
. debug.cfg
g++ $plik_compile -o $program $flagi
find $pliki_in | grep .in$ | sort -u > $katalog/lista.in
find $pliki_out | grep .out$ | sort -u > $katalog/lista.out
for in_plik in `cat $katalog/lista.in` ; do #przez wszystkie pliki in
./$program <$fifo >$out & pid=$! #odpalam program
nazwa_in=`echo "$in_plik" | sed 's/\// /g'|awk '{ print $(NF) } '| sed 's/.in$//g'` # wyciagam nazwe np ./testy/12.in da 12
outtest=`cat ${katalog}/lista.out| grep /${nazwa_in}.out$` # wybieram plik z odpowiedziami
echo $outtest
przeczytane=1 # o jeden wiecej niz liczba lini ktore zostaly przeczytane z pliku in
wyjscie=1 # o jeden wiecej niz liczba lini sprawdzonych ( plik *.out)
for liniain in `cat $in_plik`; do
if ps -aux 2>/dev/null |awk '{ print $2 }'| grep $pid ; then echo "$liniain" >> $fifo #czy nasz program dziala
else
echo "cos zdechlo"
break
fi
for linia in `tail -n +$przeczytane $out` ; do
liniatest=`cat $outtest | head -n$wyjscie | tail -n1`
echo "$liniatest"
if [ "$linia" = "$liniatest" ] ; then true #echo "$linia"
else
echo " Powinno byc: `cat $outtest | head -n $wyjscie | tail -n1` "
echo " a jest :$linia"
echo "$debugpolecenie" > $fifo #2>/dev/null
echo "-+-+-=_=="
tail -n +$przeczytane $out
q="t"
break
fi
wyjscie=$((wyjscie + 1))
done;
if [ "$q" = "t" ] ; then break
fi
przeczytane=$((wyjscie + przeczytane))
done;
kill -9 $pid 2>/dev/null
rm $out
touch $out
done;
rm -rf $katalog
실행 로그
wytrzeszcz@wytrzeszczPC:~/Dokumenty/PG/so$ ./projekt.sh
+ ./projekt.sh
podaj -h
+ . debug.cfg
++ pliki_in=./
++ pliki_out=./
++ plik_compile=./a.cpp
++ program=a.out
++ flagi=
++ debugpolecenie=debug
+ g++ ./a.cpp -o a.out
+ find ./
+ grep '.in$'
+ sort -u
+ find ./
+ grep '.out$'
+ sort -u
++ cat /tmp/debuger9348/lista.in
+ for in_plik in '`cat $katalog/lista.in`'
+ pid=9365
+ echo 9365
9365
+ cat /tmp/debuger9348/fifo
+ ./a.out -f /tmp/debuger9348/out
++ echo ./1.in
++ sed 's/\// /g'
++ sed 's/.in$//g'
++ awk '{ print $(NF) } '
+ nazwa_in=1
++ cat /tmp/debuger9348/lista.out
++ grep '/1.out$'
+ outtest=./1.out
+ echo ./1.out
./1.out
+ przeczytane=1
+ wyjscie=1
++ cat ./1.in
+ for liniain in '`cat $in_plik`'
++ ps -aux
++ awk '{ print $2 }'
++ grep 9365
+ zycie=9365
+ '[' -n 9365 ']'
+ echo a
+ echo 'linia in: a'
linia in: a
+ cat /tmp/debuger9348/out
a
TEST: 0 a
답변1
가져오기가 제공된 후 이 줄은 파이프에서 데이터를 읽을 때까지 대기하면서 차단됩니다.
./a.out <$fifo >$out & pid=$!
누군가가 fifo에 쓸 때까지는 아무 일도 일어나지 않습니다. 이를 위해서는 또 다른 프로세스가 필요합니다. 일반적으로 백그라운드 리더 프로세스를 포크하고 포그라운드에서 FIFO에 쓰거나 그 반대로 씁니다. 여기에서 읽고 있는 다음 스크립트를 파이프에 씁니다. 이것은 말이 되지 않습니다.
게시한 다른 전체 스크립트에서 리더는 백그라운드에서 실행됩니다.
./$program <$fifo >$out &
아직 전체 대본을 읽지 않았습니다. 계속 작업해야 합니다.최소한의 완전한 예제 작성. 내 생각에 당신이 겪고 있는 문제는 한 작성자가 파이프를 닫을 때 명명된 파이프에서 읽을 때 파일 끝이 발생한다는 것입니다. 하지만 작가가 너무 많아요.
echo "$debugpolecenie" > $fifo
…
echo "$liniain" >> $fifo
( >
BTW는 >>
파이프에 거의 영향을 미치지 않지만 >>
로그 파일로 전환하는 경우 이를 사용해야 합니다.)
한 번 쓰려면 파이프를 열어야 합니다. 다른 파일 설명자에서 엽니다.
mkfifo $fifo
exec 3>$fifo
…
echo "$debugpolecenie" >&3
…
exec 3>&- # to close the fifo
또는 파이프에 작성된 모든 코드가 중괄호 안에 있는 그룹화를 사용합니다.
{
…
} 3>$fifo