24

Let’s say you started a new application in Linux (like a text editor, etc.), but you forgot to use the “&”. What command(s) would you use in order to make that process run in the background, while NOT having to CLOSE that application? In this way, you can have both processes open and separately working (e.g., the command line terminal you used to create the process and the process such as a text editor still running.?

  • Technically not but perhaps tmux gives the same functionality as desired in your question. – mkc Aug 25 '16 at 21:18
  • 1
    Don't overlook the simple alternative of opening another shell when possible. – jpmc26 Aug 25 '16 at 21:18
44

In the terminal window you would typically type Control+Z to "suspend" the process and then use the bg command to "background" it.

eg with a sleep command

$ /bin/sleep 1000
^Z[1] + Stopped                  /bin/sleep 1000
$ bg
[1]     /bin/sleep 1000&
$ jobs
[1] +  Running                 /bin/sleep 1000
$ 

We can see the process is running and I still have my command line.

  • 5
    It might be interesting to add that the process can be brought back to the foreground with the fg command, which takes the job id (specified in brackets, 1 in this case) as a parameter. It isn't specific to the use of bg and can be done on processes launched with &. – Aaron Aug 25 '16 at 12:24
14

Ctrl+Z is the way to do it, but just for completeness: the question asks for "command", and that would be (from another terminal):

kill -STOP pid_of_the_running_applications

and then of course

bg

from the application terminal.

  • 6
    kil -STOP, and then kill -CONT – Michel Billaud Aug 25 '16 at 14:33
11

In Bash:

Ctrl+Z and then bg.

Now run jobs and see the result.

  • 2
    @grooveplex Tomas answered first, so it would be more appropriate to comment below Stephen's answer, that his is basically tomas` answer with some more detail. – Anthon Aug 25 '16 at 17:10
  • 2
    We actually answered concurrently. Not surprising we both said the same thing since it's the obvious answer :-) Neither of us copied the other. My answer arrived shortly after Thomas' because I'd spent the extra time on creating and formatting the example. – Stephen Harris Aug 25 '16 at 17:14
  • 1
    And mine says it's in Bash, so they're not the same. – Tomasz Aug 25 '16 at 17:18
  • 1
    Heh, there's a potential point there. It does require the shell to have job control. Some of the first machines I worked on (SVr2 based) didn't have that in /bin/sh and so this wouldn't have worked :-) – Stephen Harris Aug 25 '16 at 17:28
1

As a preventive measure for the inconvenience of having to press CTRL-z, you could make a wrapper script for your editor to which would run your editor in the background. This way you would not need to take care of remembering to start it in the background explicitly:

    #!/bin/sh

    EDITOR="emacs" # or whatever

    if [ -z "${DISPLAY}" ]; then
      ${EDITOR} "$@"
    else
      ${EDITOR} "$@" &
    fi

Above we first try to determine if you have X server available and only then run the editor in the background (if not, many Unix editors will instead use your terminal and you do not want to run the editor as a background process in this case). It will pass all the arguments to your editor of choice verbatim ("$@") just like you provided for the wrapper script.

As for the command you are missing... Per my basic experimentation, for GUI programs that do not involve terminal, it could be as simple as first sending SIGSTOP and then SIGCONT to the foreground process (using kill command if you use shell script to implement this). You would of course need to run it in another terminal window/tab, and the difficulty would be to conveniently and in a generic fashion finding the PID that you want to send your signal to. You could by default send the two signals to all the processes of the given name (defaulting to your favorite editor and allowing using PIDs as arguments as well):

    #!/bin/sh

    EDITOR=emacs # whatever

    stop_cont_prog()
    {
      case "$1" in
        # begin with number is considered PID - this is not good 
        # enough to be taken seriously...
        [1-9]*) kill -SIGSTOP "$1"; kill -SIGCONT "$2";;
        *)      killall -SIGSTOP "$1"; killall -SIGCONT "$2";;
      esac
    }

    if [ -n "$1" ]; then
      for prog in "$@"; do stop_cont_prog "$1"; done
    else  
      stop_cont_prog "${EDITOR}"
    fi

This method correctly gave me my terminal tabs to me after running (several) emacs commands in the background. But the emacs process running in the terminal was not properly restored due to shell job control or terminal setting confusion. So this method would benefit from some sophistification.

The SIGSTOP is exactly what is send to the foreground process when you press (by common defaults) CTRL-z. Refer to stty -a output

$ stty -a
speed 38400 baud; rows 50; columns 200; line = 0;
intr = ^C; [...] start = ^Q; stop = ^S; susp = ^Z; [...]
[...]

(output abbreviated) and stty manual page:

   susp CHAR
          CHAR will send a terminal stop signal

Processes stopped using SIGSTOP signal can be restarted by sending SIGCONT. Normally it is the shell job control logic that will send the SIGCONT and take care of other necessary manipulations involved with fg and bg commands which we ignore.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.