Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Say I already have a background running command1

nohup command1 &

Now I want to submit command2 into background, But I don't want command2 to run immediately. I want command2 to start running after command1 is finished.

How can I achieve this?

share|improve this question

4 Answers 4

You haven't said which shell you are running. That helps. You are asking to sequentially use software that was created to run things in parallel. The short answer for many people is that you can't but there are some ideas that you could experiment with.

The first, and not guaranteed sequential, is to submit the work to the batch queue using the batch command. It's very simple.

Another way is to write a script that will allow you to send commands to it the way that batch does.

I suppose you could write a script that runs in the background and will only allow one background job other than itself to complete at a time.

Of all this your best bet is the batch command that is what it was created for. I can tailor my answer so much better if I know more about what the scenario is. For instance, do you need to inspect the result of the previous command before running the next command in the sequence? Why aren't you typing all the commands into a file and running the file?

Tell me more and I can help you more. Costa

share|improve this answer
    
Thank you cdr! Well, I am doing interactive PBS batch job on HPC. Use qsub -I I can directly logon one of the node. Then I can run command on that node. I use mathematica software, and use nohup math -run "<<file.m" &to run a program. Since I can interact with the node, so I won't submit all the commands in a single time using a script file. I can run command at any time if I wish. So here comes the problem, I want my background program run one by one. Because each program run in parallel mode. I don't want them fighting for CPU and Memory. I don't know whether I made myself clear? –  user15964 Nov 16 '13 at 16:00

make a sub shell ?

nohup (commancd1;command2) &
share|improve this answer
    
1. This is not valid shell syntax. nohup sh -c 'command1; command2' & would work. 2. This doesn't help here: command1 has already started. –  Gilles Nov 17 '13 at 20:06

Assuming bash and you're starting the jobs in the same shell, you may be able to make use of the builtin wait command.

wait: wait [id]
Wait for job completion and return exit status.

Waits for the process identified by ID, which may be a process ID or a
job specification, and reports its termination status.  If ID is not
given, waits for all currently active child processes, and the return
status is zero.  If ID is a a job specification, waits for all processes
in the job's pipeline.

So:

sleep 60 &
wait %%; echo nextjobs; sleep 60 &

Unfortunately wait must be called from the same shell that is the parent of the process you are waiting for. This means that you wouldn't be able to wait in the background. i.e. The above example blocks until the first job has completed and then submits the second job into the background.

share|improve this answer

If your Unix implements the fuser command, this would be the easiest way:

while [ "$(fuser nohup.out 2>/dev/null)" ]; do sleep 2; done
command2

Make sure you run it in the same directory as command1.

A bit of explanation:

When you run a command with nohup, a file named nohup.out is created to store both of the command standard output and error.

The command I suggested is monitoring this nohup.out file to see if it is still open. If that's the case, that means the first process, command1, is still running. In that case, the while loop waits for two seconds and try again. When command1 ends, the nohup.out file is no more used and the loop is left, allowing command2 to be run. Note that this won't work if another process happen to use nohup.out afterwards, like someone running tail -f nohup.out.


Edit: If you OS doesn't provide fuser, here is a portable way:

1: identify the process ID of the background process. If you just ran the nohup command, you can simply get it with this command if typed just after nohup:

pid=$!

Otherwise, use one of:

pgrep command1
ps -eo pid,comm| grep -w [c]ommand1
top

or whatever similar method and set the pid variable accordingly.

Once you you are done, run this command:

while kill -0 $pid; do sleep 2; done
command2 

It will wait for command1 to complete before launching command2.

share|improve this answer
    
Thank you jlliagre! But I am a Linux freshman. Could you explain your code a little? –  user15964 Nov 16 '13 at 15:47
    
Explanation added. –  jlliagre Nov 16 '13 at 16:32
    
Thank you! I understand your method. It seems that it is not so robust. It relies on the state of nohup.out. In my case, I always redirect the nohup.out to directory which I run the program, then this method will not gonna be working. But I have an idea. Since every nohup can be traced in command jobs, so can we just monitoring the jobs queue? That is if all previous job is done, then run new command. I don't know whether it is feasible or not, and how to achieve it. –  user15964 Nov 17 '13 at 1:56
    
and what's more, I just found fuser command is not found on my HPC –  user15964 Nov 17 '13 at 2:44
    
You didn't mention you redirect nohup to some non default file but this method can certainly be adapted to monitor a different file. As your system doesn't provide fuser, I'm updating my answer with a solution that should work with any Unix like OS. –  jlliagre Nov 17 '13 at 9:22

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.