0

My question relates to an answer posted by jbarlow to the following question: redirect COPY of stdout to log file from within bash script itself

I used the suggested script as listed below. I have to use this because I don't have access to full bash (as jbarlow points out) because I'm using a buildroot version of busybox.

#!/bin/sh

if [ "$SELF_LOGGING" != "1" ]
then
    PIPE=tmp.fifo
    mkfifo $PIPE

    # Keep PID of this process
    SELF_LOGGING=1 sh $0 $* >$PIPE &
    PID=$!

    tee logfile <$PIPE &

    # Safe to rm pipe because the child processes have references to it
    rm $PIPE    
    wait $PID

    # Return same error code as original process
    exit $?
fi

The issue I'm finding is that it appears that something can freeze up from this script. For example, an strace of a frozen script using the above code looks like:

Process 29750 attached - interrupt to quit
open("/tmp/tmp.fifo", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "/usr/bin/runStuff", 24) = 24
write(2, ": ", 2)                       = 2
write(2, "line ", 5)                    = 5
write(2, "45", 2)                       = 2
write(2, ": ", 2)                       = 2
write(2, "can't open ", 11)             = 11
write(2, "/tmp/tmp.fifo", 21)   = 21
write(2, ": ", 2)                       = 2
write(2, "no such file", 12)            = 12
write(2, "\n", 1)                       = 1
stat64("/sbin/tee", 0xbff7c20c)         = -1 ENOENT (No such file or directory)
stat64("/usr/sbin/tee", 0xbff7c20c)     = -1 ENOENT (No such file or directory)
stat64("/bin/tee", 0xbff7c20c)          = -1 ENOENT (No such file or directory)
stat64("/usr/bin/tee", {st_mode=S_IFREG|0755, st_size=18956, ...}) = 0
_exit(1)                                = ?
Process 29750 detached

What it looks like (to me, with limited knowledge in this) is that tee is ending and the parent script doesn't die. Is that correct? If so, shouldn't the lack of a readable file cause the script to end? tee is backgrounded, so obviously that has no control over the parent.

As background, there's another process that repeatedly calls this if it dies. So it's possible that using the same file is causing a lockup situation. Or maybe the rm is happening before the fifo is created?

I've considered using 'read' with a timeout, but there can be situations where nothing is logged for hours at a time.

Can the script be modified so that this doesn't lock up and the script will die if/when one of the ends of the fifo dies?

Community
  • 1
  • 1
  • 1
    The line `SELF_LOGGING=1 sh $0 $* >$PIPE &` should read `SELF_LOGGING=1 sh $0 "$@" >$PIPE &`. The difference matters when there are spaces in the arguments that should be preserved. Generally, though, using `$*` is wrong and using `"$@"` is more likely to be correct. There are exceptions, but they're relatively few and far between. – Jonathan Leffler Dec 19 '12 at 01:11
  • Good extra observation, but I'm not too sure that's the whole problem. Your answer seems correct but I'm unsure how to make sure that the application fails if the pipe fails. – tudor -Reinstate Monica- Dec 25 '12 at 03:21

0 Answers0