Usando el script de suspensión Fifo

Usando el script de suspensión Fifo
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

Intento esto pero después de la primera línea de entrada al script del programa se detiene y no responde

guión completo

#!/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

Registros de ejecución

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

Respuesta1

Dado el extracto, esta línea se bloquea, esperando leer datos de la tubería:

./a.out <$fifo >$out & pid=$!

No pasará nada hasta que alguien le escriba al quince. Este tiene que ser otro proceso. Por lo general, bifurcaría un proceso de lectura en segundo plano y escribiría en el quince en primer plano, o viceversa. Aquí estás leyendo y luego tu script escribe en la tubería: esto no tiene sentido.

En el script completo diferente que has publicado, el lector se ejecuta en segundo plano:

./$program <$fifo >$out &

No he leído tu guión completo; necesitas trabajar enescribiendo un ejemplo mínimo completo. Creo que el problema con el que te estás encontrando es que el final del archivo cuando se lee desde una canalización con nombre ocurre tan pronto como un escritor cierra la canalización. Pero tienes muchos escritores:

echo "$debugpolecenie" > $fifo
echo "$liniain" >> $fifo

( >Y >>por cierto, no hace ninguna diferencia en una tubería, pero querrás usarlo >>si alguna vez cambias a un archivo de registro).

Debes abrir la tubería para escribir exactamente una vez. Ábralo en otro descriptor de archivo.

mkfifo $fifo
exec 3>$fifo
echo "$debugpolecenie" >&3
exec 3>&-  # to close the fifo

o use agrupación, donde todo el código que escribe en la tubería está dentro de las llaves:

{
} 3>$fifo

información relacionada