Usando o script pendente Fifo

2
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

Eu tento isso, mas depois da primeira linha de entrada para o script do programa parar e não responder

Script 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

Logs de execução

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
    
por wytrzeszcz 11.05.2014 / 03:36

1 resposta

3

Dado o extrato, essa linha é bloqueada, aguardando para ler os dados do canal:

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

Nada vai acontecer até que alguém escreva para o fifo. Isso precisa ser outro processo. Normalmente, você faria um processo de leitura em segundo plano e escreveria para o fifo em primeiro plano, ou vice-versa. Aqui, você está lendo, e depois o seu script escreve no pipe: isso não faz sentido.

No script completo que você postou, o leitor é executado em segundo plano:

./$program <$fifo >$out &

Eu não li o seu script completo - você precisa trabalhar em escrevendo um exemplo mínimo completo . Eu acho que o problema que você está enfrentando é que o fim do arquivo ao ler de um pipe nomeado acontece assim que um escritor fecha o pipe. Mas você tem muitos escritores:

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

( > e >> não fazem diferença em um pipe, a propósito, mas você vai querer usar >> se você mudar para um arquivo de log.)

Você precisa abrir o pipe para escrever exatamente uma vez. Abra-o em outro descritor de arquivos.

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

ou use o agrupamento, em que todo o código que grava no pipe está dentro das chaves:

{
  …
} 3>$fifo
    
por 12.05.2014 / 02:53