Coder Perfect

what does “bash:no job control in this shell” mean?


I believe it has something to do with the parent process spawning a new subprocess that doesn’t have a tty. Is there anyone who can explain what’s going on under the hood? i.e. the bash working model, process generation, and so on?

Because this is a large topic, references to relevant blogs are also welcome. I’ve been searching for a long, but all of the results are about a very particular case, and none of them are about the backstory. To give you some background, here’s the shell script that produced the message ‘bash: no job control in this shell’.

#! /bin/bash

while [ 1 ]; do
    st=$(netstat -an |grep 7070 |grep LISTEN -o | uniq)
    if [ -z $st ]; then
        echo "need to start proxy @$(date)"
        bash -i -c "ssh -D 7070 -N > /dev/null"
        echo "proxy OK @$(date)"
    sleep 3

This line:

bash -i -c “ssh -D 7070 -N > /dev/null”

This is the source of “bash:no job control in this shell.”

Asked by luanjunyi

Solution #1

It’s possible that you’ll need to enable job control:

#! /bin/bash   
set -m

Answered by Marian

Solution #2

Job control is a set of shell and tty driver features that enable the user to manage many jobs from a single interactive shell.

A job is either a single command or a series of commands. It’s a job if you run ls. Even if you run ls|more, you’re still only doing one job. Unless they are expressly separated, if the command you run starts subprocesses of its own, they will all belong to the same task.

You can place a job in the background even if you don’t have job control by adding & to the command line. That’s pretty much all the power you have.

You can also do the following with job control:

The jobs command displays a list of jobs that the shell keeps track of. Each is given a job number (which is different from the PIDs of the processes that make up the task). To pick a job to foreground or background, use the job number, preceded with percent, as an argument to fg or bg. The kill command in the shell accepts the percent jobnumber notation as well. This is advantageous since job numbers are assigned starting at 1 and are hence shorter than PIDs.

You may also use the shortcuts percent + for the most recently foregrounded work and percent – for the previously foregrounded job to quickly switch between two jobs with CtrlZ followed by fg percent – (suspend one, resume the other) without having to remember the numbers. Alternatively, you might use the command’s commencement. If you’ve suspended a ffmpeg command, resuming it is as simple as typing fg percent ffffffffffffffffffffffffffffffffffff (assuming no other active jobs start with “ff”). Last but not least, you don’t have to input the fg. Simply typing percent – as a command brings up the preceding task.

“However, why do we require this?” I’m sure you’re wondering. “If I wish to perform another command, I can just start another shell.” True, multitasking can be done in a variety of ways. On a typical day, I have login shells running on tty1 through tty10 (yes, there are more than 6, you just have to enable them), one of which will be running a screen session with four screens, another might have an ssh running in which another screen session is running on the remote machine, and my X session with three or four xterms. I continue to use job control.

CtrlZ, run the commands, and fg is natural and quick if I’m in the middle of vi or less or aptitude or any other interactive thing and need to run a couple of other brief commands to decide how to proceed. (Many interactive programs provide a! keybinding to run an external command for you; I don’t think this is as good because you don’t get the advantages of your shell’s history, command line editor, or completion system.) When I see someone open a second xterm/screen/whatever to run one command, stare at it for two seconds, and then exit, it makes me sad.

Now, let’s talk about your script. In overall, it does not appear to have been written competently. The particular line in question is:

bash -i -c "ssh -D 7070 -N > /dev/null"

is perplexing I’m not sure why the ssh command is being passed to a separate shell rather than being executed directly from the main script, let alone why the -i option was introduced. The -i option instructs the shell to operate interactively, allowing job control to be activated (among other things). However, it is not being used interactively. Whatever the reason for the separate shell and -i, the warning regarding job control was an unintended consequence. I’m presuming it was a hack to get around an ssh feature that was bothering you. When you do anything like that, you should comment on it.

Answered by Alan Curry

Solution #3

Not having access to the tty is one of the possibilities.

Under the hood:

The remarks from the bash source code were only partially quoted.

In response to the question’s author’s supplementary request: This is where you’ll find bash.

If you can read C code, acquire the source tarball; you’ll find work inside. c – that one will explain more “behind the scenes” information.

Answered by favoretti

Solution #4

On my own embedded system, I ran into a difficulty and was able to solve it by running the getty process with “setsid,” which, according to its manpage, creates a new process with a new session id.

Answered by Heiko Gerstung

Solution #5

This issue arose solely as a result of mistyping a previously executed command into zsh with the percent prefix, such as percent echo this instead of echo this. To such a silly misspelling, the error was quite unclear.

Answered by Ivan Klass

Post is based on