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?
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?
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
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
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.
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
.
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 01:56
fuser
, I'm updating my answer with a solution that should work with any Unix like OS.
– jlliagre
Nov 17 '13 at 09:22
make a sub shell ?
nohup (commancd1;command2) &
nohup sh -c 'command1; command2' &
would work. 2. This doesn't help here: command1
has already started.