What Does "Bash:No Job Control in This Shell" Mean

Why can't I use job control in a bash script?

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".

wget and bash error: bash: line 0: fg: no job control

It looks like the solution is to avoid the -I parameter for xargs which, per the OS X xargs man page, has a 255-byte limit on the replacement string. Instead, the -J parameter is available, which does not have a 255-byte limit.

So my command would look like:

echo "wget --no-check-certificate --no-verbose -O a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg" | xargs -J % bash -c %

However, in the above command, only the portion of the replacement string before the first whitespace is passed to bash, so bash tries to execute:

wget

which obviously results in an error. My solution is to ensure that xargs interprets the commands as null-delimited instead of whitespace-delimited using the -0 parameter, like so:

echo "wget --no-check-certificate --no-verbose -O a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg" | xargs -0 -J % bash -c %

and finally, this works!

Thank you to @CharlesDuffy who provided most of this insight. And no thank you to my OS X version of xargs for its poor handling of replacement strings that exceed the 255-byte limit.

Emacs shell-command outputting cannot set terminal process group and no job control in this shell

Never mind, it was because of this:

(set-variable 'shell-command-switch "-ic")

How to tell bash not to issue warnings cannot set terminal process group and no job control in this shell when it can't assert job control?

man bash says about set options that The options can also be specified as arguments to an invocation of the shell. Note you will need +m not -m. Admittedly the manual isn't quite clear on that.

However looking at bash source code (version 4.2), apparently it ignores the state of this flag. I would say this is a bug.

Applying the following small patch makes bash honor the m flag on startup. Unfortunately this means you will have to recompile bash.

--- jobs.c.orig 2011-01-07 16:59:29.000000000 +0100
+++ jobs.c 2012-11-09 03:34:49.682918771 +0100
@@ -3611,7 +3611,7 @@
}

/* We can only have job control if we are interactive. */
- if (interactive == 0)
+ if (interactive == 0 || !job_control)
{
job_control = 0;
original_pgrp = NO_PID;

Tested on my linux machine where job control is available by default, so the error messages you see on mingw are not printed here. You can still see that bash honors the +m now, though.

$ ./bash --noprofile --norc
$ echo $-
himBH
$ fg
bash: fg: current: no such job
$ exit
$ ./bash --noprofile --norc +m
$ echo $-
hiBH
$ fg
bash: fg: no job control


Related Topics



Leave a reply



Submit