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
Ich versuche dies, aber nach der ersten Eingabezeile stoppt das Programmskript und reagiert nicht
Vollständiges Skript
#!/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
Ausführungsprotokolle
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
Antwort1
Angesichts des Auszugs blockiert diese Zeile und wartet darauf, Daten aus der Pipe zu lesen:
./a.out <$fifo >$out & pid=$!
Es passiert nichts, bis jemand in die FIFO schreibt. Dies muss ein anderer Prozess sein. Normalerweise würden Sie einen Leseprozess im Hintergrund abzweigen und im Vordergrund in die FIFO schreiben oder umgekehrt. Hier lesen Sie und später schreibt Ihr Skript in die Pipe: Das ergibt keinen Sinn.
In dem anderen vollständigen Skript, das Sie gepostet haben, läuft der Reader im Hintergrund:
./$program <$fifo >$out &
Ich habe Ihr Skript nicht vollständig gelesen. Sie müssen daran arbeiten.Schreiben eines minimalen vollständigen Beispiels. Ich denke, das Problem, auf das Sie stoßen, ist, dass das Dateiende beim Lesen aus einer benannten Pipe eintritt, sobald ein Writer die Pipe schließt. Aber Sie haben viele Writer:
echo "$debugpolecenie" > $fifo
…
echo "$liniain" >> $fifo
( >
und >>
macht übrigens bei einer Pipe keinen Unterschied, Sie werden es aber verwenden wollen, >>
wenn Sie jemals zu einer Protokolldatei wechseln.)
Sie müssen die Pipe zum Schreiben genau einmal öffnen. Öffnen Sie sie auf einem anderen Dateideskriptor.
mkfifo $fifo
exec 3>$fifo
…
echo "$debugpolecenie" >&3
…
exec 3>&- # to close the fifo
oder verwenden Sie eine Gruppierung, bei der der gesamte Code, der in die Pipe schreibt, innerhalb der Klammern steht:
{
…
} 3>$fifo