views:

1406

answers:

4
+3  A: 

What he meant is that job control is by default turned off in non-interactive mode (i.e. in a script.)

From the bash man page:

JOB CONTROL
       Job  control refers to the ability to selectively stop (suspend)
       the execution of processes and continue (resume) their execution at a
       later point.
       A user typically employs this facility via an interactive interface
       supplied jointly by the system’s terminal driver and bash.

and

   set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
      ...
      -m      Monitor mode.  Job control is enabled.  This option is on by
              default for interactive shells on systems that support it (see
              JOB CONTROL above).  Background processes run in a separate
              process group and a line containing their exit status  is
              printed  upon  their completion.

When he said "is stupid" he meant that not only:

  1. is job control meant mostly for facilitating interactive control (whereas a script can work directly with the pid's), but also
  2. I quote his original answer, ... relies on the fact that you didn't start any other jobs previously in the script which is a bad assumption to make. Which is quite correct.

UPDATE

In answer to your comment: yes, nobody will stop you from using job control in your bash script -- there is no hard case for forcefully disabling set -m (i.e. yes, job control from the script will work if you want it to.) Remember that in the end, especially in scripting, there always are more than one way to skin a cat, but some ways are more portable, more reliable, make it simpler to handle error cases, parse the output, etc.

You particular circumstances may or may not warrant a way different from what lhunath (and other users) deem "best practices".

vladr
+1 Accurately detailed. Job control is a feature to make handling jobs on the (interactive) prompt more convenient. There is no reason why anyone would want it in scripts as you can just keep the PIDs of your background processes and *wait* on or *kill* them.
lhunath
Thanks! Weird that the man page has better info than the bash.info file.
system PAUSE
Ok, I *get* that a hard-coded job number is a bad idea. No issue there. But words like "*by default* for interactive" and "user *typically* employs" and "meant *mostly* for" all hint strongly that there is *some* esoteric use case for job control in a script. Otherwise set -m should fail in scripts.
system PAUSE
+1  A: 

Bash does support job control, as you say. In shell script writing, there is often an assumption that you can't rely on the fact that you have bash, but that you have the vanilla Bourne shell (sh), which historically did not have job control.

I'm hard-pressed these days to imagine a system in which you are honestly restricted to the real Bourne shell. Most systems' /bin/sh will be linked to bash. Still, it's possible. One thing you can do is instead of specifying

#!/bin/sh

You can do:

#!/bin/bash

That, and your documentation, would make it clear your script needs bash.

Peter
On Ubuntu, /bin/sh is not linked to Bash. So you need #!/bin/bash.
emk
+1  A: 

Job control is useful only when you are running an interactive shell, i.e., you know that stdin and stdout are connected to a terminal device (/dev/pts/* on Linux). Then, it makes sense to have something on foreground, something else on background, etc.

Scripts, on the other hand, doesn't have such guarantee. Scripts can be made executable, and run without any terminal attached. It doesn't make sense to have foreground or background processes in this case.

You can, however, run other commands non-interactively on the background (appending "&" to the command line) and capture their PIDs with $!. Then you use kill to kill or suspend them (simulating Ctrl-C or Ctrl-Z on the terminal, it the shell was interactive). You can also use wait (instead of fg) to wait for the background process to finish.

Juliano
system PAUSE
A: 

Possibly o/t but I quite often use nohup when ssh into a server on a long-running job so that if I get logged out the job still completes.

I wonder if people are confusing stopping and starting from a master interactive shell and spawning background processes? The wait command allows you to spawn a lot of things and then wait for them all to complete, and like I said I use nohup all the time. It's more complex than this and very underused - sh supports this mode too. Have a look at the manual.

You've also got

kill -STOP pid

I quite often do that if I want to suspend the currently running sudo, as in:

kill -STOP $$

But woe betide you if you've jumped out to the shell from an editor - it will all just sit there.

I tend to use mnemonic -KILL etc. because there's a danger of typing

kill - 9 pid # note the space

and in the old days you could sometimes bring the machine down because it would kill init!

Ghoti
OT but interesting info. Very very OT: is your name pronounced the same as "fish"?
system PAUSE
Yes, my family name is Fish and I quite often use ghoti and see if anyone notices!
Ghoti