Interactive shell through a pipe

I'm new to working with pipes, so I don't know whether the following is expected behaviour or a bug on the part of an application.

Since Version 0.47, Inkscape provides a non-GUI interactive shell mode of operation. I am trying to time the program's performance in converting SVG files to PNG images and compare this to other apps. Inkscape expects a line of optional arguments and a file name to be delivered to its command prompt. (see the bottom part of Chapter 24. Using the Command Line for an example how it works) I am using a named pipe for delivering these lines. My benchmarking scripts are these:

svgbench.sh

#!/bin/bash

export BASEDIR=~/PNGs
export SVGDIR=$BASEDIR/svg
export SCRDIR=$BASEDIR/scripts
export WIDTH=600
 
mkfifo in.fifo
mkfifo out.fifo
inkscape --shell <in.fifo >>out.fifo 2>>$SCRDIR/error &
                                           # start Inkscape in shell mode
                                           # and link stdin and stdout to named pipes

i=1
while [ $i -le 5 ]                         # multiple runs through all tested apps
do
    echo "Inkscape-shell" >>$SCRDIR/error  # time Inkscape
    /usr/bin/time --format 'Inkscape-shell     %e\t%U\t%S' -a --output=$SCRDIR/times $SCRDIR/inkscape-shell.sh
    echo "Rsvg" >>$SCRDIR/error            # time Gnome's librsvg
    /usr/bin/time --format 'rsvg               %e\t%U\t%S' -a --output=$SCRDIR/times $SCRDIR/rsvg.sh
    echo "" >> $SCRDIR/times
    i=`expr $i + 1`
done

echo "quit" >> in.fifo                     # quit Inkscape
rm in.fifo
rm out.fifo

inkscape-shell.sh

#!/bin/bash

for TESTFILE in `ls $SVGDIR`   # get a list of test files
do
    echo $TESTFILE " ">>$SCRDIR/error
    OUTFILE=$(basename $TESTFILE .svg).png
    TESTFILE=$SVGDIR/$TESTFILE
    echo "-w $WIDTH -y 0.0 -e $BASEDIR/inkscape1/$OUTFILE $TESTFILE"
                               # command line for Inkscape
    read -sd ">" < out.fifo    # wait until input prompt gets thrown back
done >> in.fifo
echo >>$SCRDIR/error

As you can see, the pipe Inkscape gets its commands from is accessed consecutively from different processes (one for every test loop, and the 'quit' command), and there are times when the pipe in.fifo is not connected to any file descriptor. Whenever this happens, Inkscape quits, even if no explicit quit command is given.

I have tracked this behaviour back to this: man pipe(7) states "If all file descriptors referring to the write end of a pipe have been closed, then an attempt to read from the pipe will see end-of-file (read will return 0)." Looking closely at the accordant source code of Inkscape, I think what happens is that

  • stdin is read continuously in a loop
  • fgets() in line 01059 means that an EOF will cause the loop and consequently the programm to quit.

Now my question: is this the expected behaviour of an interactive shell program, or should it be perceived as a bug?

And if it is to be expected, how could I achieve a timed execution of inkscape-shell.sh without forking to a new process? Are there other ways to feed lines to an interactive shell?

Hi.

Responding only to your question:

Many find a solution in the non-trivial system expect:

INTRODUCTION
       Expect  is a program that "talks" to other interactive programs accord-
       ing to a script.  Following  the  script,  Expect  knows  what  can  be
       expected  from  a  program and what the correct response should be.

-- excerpt from man expect

Best wishes ... cheers, drl