2

I have a shell script similar to the following:

#!/bin/bash

# Here is where I set a bunch of environment variables that are
# used by the process invoked below...

# Now I want to invoke the process in the background and redirect
# all of the output to a log file.
nohup name-of-executable > logfile.out 2>&1 &

# Finally, I record the PID of the process before the script exits.
echo $! > proc.pid

The use case is that periodically, someone will ssh into this machine, kick off this process and then log out of the machine. I just need to have the log file created so I can debug any issues encountered during the execution of the process.

When using my script above, the process executes correctly, the logfile is created, but no output ever gets written to the log file. I just get a zero-length file.

If I run the command nohup name-of-executable > logfile.out 2>&1 & directly from the command line, the process executes and logs data as expected. I just don't know how to do this as part of a shell script.

8
  • Do you only have one instance of the script running when you get the empty log file? Remember that the shell redirection command > file clears the file when the command is started. – Lucas Apr 13 '16 at 11:44
  • What operating system? – Mark Plotnick Apr 13 '16 at 19:49
  • @Lucas, yes there is only one instance. Thanks. – Del Putnam Apr 13 '16 at 20:22
  • @Mark Plotnick, we're using Red Hat 7. – Del Putnam Apr 13 '16 at 20:23
  • Can you try this? Change the line in the script from nohup name-of-executable > logfile.out 2>&1 & to nohup strace -f -o strace.out name-of-executable > logfile.out 2>&1 & After the process exits, check the last few lines of strace.out and see if it got a signal or something. – Mark Plotnick Apr 13 '16 at 20:40
3

How about using screen instead of nohup? You could do background processing like this

screen -d -m /bin/bash 'name-of-executable > logfile.out 2>&1'

It is better than nohup because it lets you see what is going on with your background job. You could issue screen -ls to see a list of all jobs and then screen -r screen_identifier to jump directly to the interactive shell of that background job. Type man screen for more info.

2
  • Thanks for the suggestion, but there's really no other command line interactivity with this process, so I never need to pull it back into the foreground. I just want to have it kicked off from within the shell script for convenience. The script first sets a bunch of environment variables that are used by the process. Then it changes to the appropriate directory, kicks off the process and logs the process ID to a file. – Del Putnam Apr 13 '16 at 11:28
  • I mentioned that because it's really usefull tool for debugging. If your only desire is to make it run in the background you can do it easly with example I provided. – Inclooder Apr 13 '16 at 12:53
1

Based on what's been said in the comments, this might do what you require:

#!/bin/sh

nohup sh -c "sleep 5 && ls /proc/1/fd /proc/$$ >/tmp/log 2>/tmp/log.err" &

echo $$ >>/tmp/pid_log    
wait
echo done

The output looks something like this:

$ grep . /tmp/log{,.err}
/tmp/log:uid_map
/tmp/log:wchan
/tmp/log.err:ls: cannot open directory /proc/1/fd: Permission denied

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.