Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am seeing some strange behaviour that I have not encountered before in bash.

It seems that if I redirect stderr and stdout to a file for a process and I then tail that file and send a ctrl-c interrupt to the tail process, then the original process is stopped!

Example:

$ ./ec2_backup.sh > backup.out 2>&1 &
$ tail -f backup.out
pending
Checking instance i-a3214dc7
running
Instance i-a3214dc7 is running.

^C
[1]+  Stopped                 ./ec2_backup.sh > backup.out 2>&1

The environment is Ubuntu 10.04 bash terminal logged in over ssh via Mac.

Could anyone explain this to me?

Thanks!

share|improve this question
add comment

2 Answers

up vote 0 down vote accepted

I dont think the CTRL+C on the tail is the issue here. I'm betting the job is getting stopped while the tail is running, but you dont see it as bash doesnt tell you such things until right before it shows you a shell prompt (this behavior is default and can be changed with set -b).

What I'm thinking is happening is your job is doing something with the TTY. Whenever a backgrounded application tries to read from the TTY, it receives a SIGTTIN. This is because its in the background, and should not be interacting with the user, and so the SIGTTIN results in the process being stopped (not killed, stopped). Additionally if you have stty tostop set and the application tries to write any output to the TTY then it will also be stopped.
Even though you redirect stdin and stdout, it is still possible for applications which have been backgrounded to figure out what TTY theyre on and try to access it directly.

Edit (to answer your comment):
I've had similar issues with a backgrounded ssh as well. I dont know why it tries to access the TTY, but it does, and it gets a SIGTTIN because of it.

You could try wrapping your command in script.

script -c ./ec2_backup.sh /dev/null &>/dev/null </dev/null &

Script creates a TTY for processes to interact with and redirects this TTY to/from STDIN/STDOUT. Now applications that think theyre interacting with a full TTY, are really only interacting with the simple STDIN and STDOUT pipes. This way you can now redirect STDIN and STOUT to /dev/null and the backgrounded application wont be able to try and grab the TTY (and get a SIGTTIN from attempting to do so).

share|improve this answer
    
I think you are right, the ctrl + c does not seem to be the cause. It does seem that the parent task is being stopped after certain child processes are launched (specifically launching remote commands over ssh). The remote commands being issued over ssh has the following options: -i $id_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=$KNOWN_HOSTS -t . After these commands the process does not seem to be started again upon completion and I have to bring it to the foreground, and then send to background in order for it to continue. Any ideas how to have the process continue automatically? –  Symfrog Mar 16 '12 at 9:43
    
@symfrog I edited my answer with a possible solution to your issue –  Patrick Mar 16 '12 at 9:58
add comment

Use

nohup ./ec2_backup.sh > backup.out 2>&1 &
share|improve this answer
    
Thanks, I was thinking that the ctrl-c interrupt on tail may not be the cause of the stopped process. The backup script launches several child processes. Could it be that the parent process gets automatically stopped by bash while a child process is running and that this is reported by the shell after interrupting the tail process? –  Symfrog Mar 16 '12 at 8:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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