Verwenden des Fifo-Hang-Skripts

Verwenden des Fifo-Hang-Skripts
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

verwandte Informationen