4

I have bash script that logs to two log files in parallel.

echo "$(date) | [STATE] Activating IP forwarding" >> $logsPath$logFileName
echo $(date +"%Y-%m-%d %H:%M")","$previousState >> $logsPath$usageStatsFileName
echo $(date +"%Y-%m-%d %H:%M")","$currentState >> $logsPath$usageStatsFileName

It works fine if I run script in foreground, but when I send it to background nothing is logged to these files.

nohup nice ./rfid_reader.sh&

Can you give me some hint what shall I do to be able to run script in background and still have logs in mentioned two files?

  • check the values of the filename vars inside the script – RSFalcon7 Mar 24 '14 at 23:22
  • Could you show us the entire script? How are those variables set? What OS are you using? Which version of it? Which shell? – terdon Mar 25 '14 at 0:00
  • I think this might be a nohup issue, if you are using bash, you could try nice ./rfid_reader.sh </dev/null &>/dev/null & disown as an alternative and see if this solves it. Otherwise it is surely an issue elsewhere as @terdon says. – Graeme Mar 25 '14 at 0:03
2

IMPORTANT NOTE:

This is almost certainly irrelevant to this question. I am leaving it here since it might help someone else but, at least with my version of nohup on Debian, the internal redirects are not affected, nohup will only capture the stderr and stdout of the script.


By default, nohup will print all output to nohup.out. It normally informs you of this but you can't see it because you're running in the background. FOr example, try:

$ nohup echo "foo"
nohup: ignoring input and appending output to ‘nohup.out’

To avoid this, you need to explicitly redirect the program's output:

$ nohup echo "foo" > bar
nohup: ignoring input and redirecting stderr to stdout

So, you need to run your script, and redirect it's output. Both the standard error and standard output streams will be redirected to the same file:

nohup nice ./rfid_reader.sh > output_file &

This is actually a reasonable default for nohup since the whole point of it is to let you close your terminal session and leave it running in the background, so having it print to the terminal would defeat its purpose.

  • 1
    Be careful w/ nohup, different versions work differently across various Unixes. one-liner: How to Properly Use nohup – slm Mar 25 '14 at 0:01
  • @slm yeah, I just edited. Graeme just pointed out that there's no reason why nohup would affect the internal redirects to files. facepalm. Thanks for that link, very educational. – terdon Mar 25 '14 at 0:02
1

You don't really need nohup you know. In fact, I've personally never found a use for it.

( ./rfidreader.sh 1>&2 & ) 2>&- &

That'll detach your process from the terminal, it'll keep doing whatever it's supposed to do and should keep from breaking stuff.

Demo Script

cat <<-\DEMO >|${s=/tmp/script} 
printf 'tty is %s\nparent pid is %s\npid is pid=%s\n' \
     "$(tty)" "$PPID" "$$"
exec 1>&2 ; nums=$(seq 0 9)
rm ${files=$(printf "/tmp/file%s\n" $nums)}
for n in $nums ; do { for f in $files ; do
    echo "Line $n" >>"$f" ; done
sleep 1 ; } ; done
#END
DEMO

Run Demo

s=/tmp/script ;chmod +x $s ;info="$(($s &)2>&- &)"
echo "$info" ; pid="${info##*=}" ; echo
while ps -p $pid >/dev/null ; do sleep 3 ; done
for f in /tmp/file[0-9] ; do
    printf 'path : %s\tline count : %s\n' \
        $f $(<$f wc -l)
done

Output:

tty is not a tty
parent pid is 1
pid is 12123

path : /tmp/file0    line count : 10
path : /tmp/file1    line count : 10
path : /tmp/file2    line count : 10
path : /tmp/file3    line count : 10
path : /tmp/file4    line count : 10
path : /tmp/file5    line count : 10
path : /tmp/file6    line count : 10
path : /tmp/file7    line count : 10
path : /tmp/file8    line count : 10
path : /tmp/file9    line count : 10

The above demonstrates. It builds and runs a script named /tmp/script, chmod's it as executable, and runs it in the &background of a &backgrounded ( subshell ).

The script rms /tmp/file0-9 10 files and echoes a line every second into all 10 of them. I capture some $info from the disowned process and present it via $(command substitution). While ps still reports on the $pid I capture, I know it still runs so I sleep. When it completes, the lines in all 10 files are counted with wc.

After you invoke a process in this way you can freely close its original parent process and it will keep on trucking - it's effectively disowned.

Worth mentioning, I think, is that the process is actually initially called in $(command substitution) and printfs me the $info I want so I can effectively control it. But as soon as it drops its terminal output with exec 1>&2 (which is closed in the same subshell with 2>&-), the process escapes and I have to wait around for it on the other end. Kinda the best of both worlds, especially if you use it to handle input pipes, so long as you can wrap your mind around all of the redirections and process leaders.

Everything else is just for demonstration here. All you need to run this is the top script and:

info="$(($script_path &)2>&- &)"    

NOTE: This only prints to terminal exactly what I wished to demonstrate it. As noted by the $PPID, this process is disowned by the terminal and is a direct child of $PID 1.

0

Thanks to all of you for the answers. I've learnt a lot from them. Problem is solved. Nohoup does not disturb logging to external files. Source of my problem was most probably in system performance as I am working with embeded linux. Not knowing what to do I rebooted system and started script in background once again. Now it works.

Issue is somehow solved but question arrises why reboot was necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.