LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-01-2006, 03:19 PM   #1
unholy
Member
 
Registered: Sep 2003
Location: Eire
Distribution: Ubuntu 7.10
Posts: 344

Rep: Reputation: 30
Question What do 'bg' and 'fg' actually do?


Can anyone tell me what the 'bg' and 'fg' commands are? I know that when I run a program from the console with & (ampersand) at the end, I am given control of the console again, instead of waiting for the program to return. I also know that running 'fg' will bring the program back so that it does block the console again. This is useful because I can CTRL^C to kil lthe program.

What I don't understand is what is actuall happening here. Also, when I run a program with & at the end, it doesn't show with 'ps -A'.

Can anyone explain these things to me?

Thanks,
unholy
 
Old 10-01-2006, 03:25 PM   #2
sdexp
Member
 
Registered: Sep 2003
Location: USA
Distribution: Ubuntu Linux
Posts: 103

Rep: Reputation: 15
bg is a program which brings back a suspended process running into the background.

For example, if you pressed Ctrl+z on "ls -R /" (which takes a long time usually), then it stops.

Type "bg" and then it runs in the background. Run "fg" and then it will be in the foreground.

You can supply an argument to bg and fg which refers to the number of the process (PID). This information is printed to the screen if you use the "ps" command.

About not having background processes show in ps -A, try ps -a also. ps -e and ps -A are more comprehensive, but your distibution may have different options.

Last edited by sdexp; 10-07-2006 at 02:04 PM.
 
Old 10-01-2006, 05:52 PM   #3
Markie1006
LQ Newbie
 
Registered: Oct 2006
Distribution: Slackware
Posts: 12

Rep: Reputation: 0
The fg, bg & jobs commands are used for shell job control.

First lets kick off a job/process in the background, adding the '&'.
We then check the status of the process using the 'jobs' command, which will also show any other processes this shell has control of.
Code:
mbp:~$ sleep 9999 &
[1] 16385
mbp:~$ jobs
[1]+  Running                 sleep 9999 &
You can then bring your process back to the foreground using 'fg'
Code:
mbp:~$ fg
sleep 9999
To put it back into the background again and free up the shell, you need to hit ctrl-z.
After hitting ctrl-z, the shell will inform you the process has been stopped (confirmed by the 'jobs' command), but you will have regained control of the shell.
Code:
[1]+  Stopped                 sleep 9999
mbp:~$ jobs
[1]+  Stopped                 sleep 9999
To start it running again, type 'bg'.
Again you can see the status confirmed by the 'jobs' command.
Code:
mbp:~$ bg
[1]+ sleep 9999 &
mbp:~$ jobs
[1]+  Running                 sleep 9999 &
You can also kill processes by their 'job number' too
Code:
mbp:~$ kill %1

[1]+  Stopped                 sleep 9999
mbp:~$ jobs
[1]+  Terminated              sleep 9999

Last edited by Markie1006; 10-01-2006 at 05:54 PM.
 
Old 10-01-2006, 09:38 PM   #4
jon23d
Member
 
Registered: May 2006
Location: Kennewick, WA - USA
Distribution: Ubuntu
Posts: 129

Rep: Reputation: 15
I use emacs as a development environment. I know that I can access a shell from it, but I think it is easier to just stop the program with ctrl-z, do what I need to do, and then bring it back with fg. It's kind of like pause.
 
Old 10-01-2006, 09:39 PM   #5
zetabill
Member
 
Registered: Oct 2005
Location: Rhode Island, USA
Distribution: Slackware, Xubuntu
Posts: 348

Rep: Reputation: 32
Post Shell Jobs

Just to add to Markie1006's excellent explanation of shell jobs, the fg and bg commands can accept as arguments the job number as well.

An example you can do right at home in your own shell:
Code:
bill@yogi:~$ sleep 9991 &
[1] 10088
bill@yogi:~$ sleep 9992 &
[2] 10090
bill@yogi:~$ sleep 9993 &
[3] 10092
bill@yogi:~$ jobs
[1]   Running                 sleep 9991 &
[2]-  Running                 sleep 9992 &
[3]+  Running                 sleep 9993 &
Notice the + and - signs next to the second and third jobs. The + next to the third job means that it is at the top of the job manager queue. The - next to the second job means it's second in that queue. They have those designations now because they were the most recent (+) and most previous (-) jobs started. These are status indicators. The + also refers to a "current" job.

Whenever you invoke the fg or bg command, it will take the job with a + as the argument to the command. Since you have three jobs running, that might not be very convenient should you need to access the first job. In which case you can invoke `fg 1` to foreground the first job. Once you do that, the job gets the + designation and the - designation moves to where the + was.
Code:
bill@yogi:~$ fg 1
sleep 9991

[1]+  Stopped                 sleep 9991
bill@yogi:~$ jobs
[1]+  Stopped                 sleep 9991
[2]   Running                 sleep 9992 &
[3]-  Running                 sleep 9993 &
I stopped the job so I could show you the example shown in the jobs output. Follow? It gets even better...

Since a foregrounded job gets precedence there can be only one; thus the fg command can only accept one argument (not positive but I can't get it to accept anything else). The bg command can, however, accept more than one argument. If you go through (using the fg command) and ctrl-z stop all three processes then you can use the bg command to either cycle through the designated queue to background everything again, or you can explicitly set them to the background in one command:
Code:
bill@yogi:~$ jobs
[1]   Stopped                 sleep 9991
[2]-  Stopped                 sleep 9992
[3]+  Stopped                 sleep 9993
bill@yogi:~$ bg
[3]+ sleep 9993 &
bill@yogi:~$ bg
[2]+ sleep 9992 &
bill@yogi:~$ bg
[1]+ sleep 9991 &
Code:
bill@yogi:~$ bg 1 2 3
[1]+ sleep 9991 &
[2]+ sleep 9992 &
[3]+ sleep 9993 &
bill@yogi:~$ jobs
[1]   Running                 sleep 9991 &
[2]-  Running                 sleep 9992 &
[3]+  Running                 sleep 9993 &
One thing to note, however. If all three jobs are running, then the last job initially executed will have the + designation and the second-to-last will have the - designation regardless of how you manipulate them. If two are running and one is stopped, then the stopped job will have a + and if two are stopped and one if running then the last stopped job will have the +. Stopped jobs apparently get precedence to the bg and fg commands. That's very confusing but the more you play with it you'll understand it. Here's an example that best illustrates my last paragraph:
Code:
bill@yogi:~$ bg 3 1 2
[3]- sleep 9993 &
[1]- sleep 9991 &
[2]+ sleep 9992 &
bill@yogi:~$ jobs
[1]   Running                 sleep 9991 &
[2]-  Running                 sleep 9992 &
[3]+  Running                 sleep 9993 &
bill@yogi:~$ fg 2
sleep 9992

[2]+  Stopped                 sleep 9992
bill@yogi:~$ fg 3
sleep 9993

[3]+  Stopped                 sleep 9993
bill@yogi:~$ fg 1
sleep 9991

[1]+  Stopped                 sleep 9991
bill@yogi:~$ jobs
[1]+  Stopped                 sleep 9991
[2]   Stopped                 sleep 9992
[3]-  Stopped                 sleep 9993
bill@yogi:~$ bg 2
[2] sleep 9992 &
bill@yogi:~$ jobs
[1]+  Stopped                 sleep 9991
[2]   Running                 sleep 9992 &
[3]-  Stopped                 sleep 9993
The `jobs` command also accepts arguments. If you check the references I included at the end you'll know that there are a few interesting ones. One thing it doesn't really talk about is the ability to use status as the argument.
Code:
bill@yogi:~$ jobs
[1]   Stopped                 sleep 9991
[2]-  Stopped                 sleep 9992
[3]+  Stopped                 sleep 9993
bill@yogi:~$ jobs + -
[3]+  Stopped                 sleep 9993
[2]-  Stopped                 sleep 9992
bill@yogi:~$ jobs - +
[2]-  Stopped                 sleep 9992
[3]+  Stopped                 sleep 9993
bill@yogi:~$ jobs 1
[1]   Stopped                 sleep 9991
bill@yogi:~$ jobs -
[2]-  Stopped                 sleep 9992
Well I hope that answered your question. As far as I know there's no real way to change the priority of a job without stopping one. I'm speculating that job priority is related to process priority and that I don't know too much about... yet.


References:
Code:
bill@yogi:~$ help jobs
jobs: jobs [-lnprs] [jobspec ...] or jobs -x command [args]
     Lists the active jobs.  The -l option lists process id's in addition
    to the normal information; the -p option lists process id's only.
    If -n is given, only processes that have changed status since the last
    notification are printed.  JOBSPEC restricts output to that job.  The
    -r and -s options restrict output to running and stopped jobs only,
    respectively.  Without options, the status of all active jobs is
    printed.  If -x is given, COMMAND is run after all job specifications
    that appear in ARGS have been replaced with the process ID of that job's
    process group leader.
bill@yogi:~$ help bg
bg: bg [job_spec ...]
     Place each JOB_SPEC in the background, as if it had been started with
    `&'.  If JOB_SPEC is not present, the shell's notion of the current
    job is used.
bill@yogi:~$ help fg
fg: fg [job_spec]
     Place JOB_SPEC in the foreground, and make it the current job.  If
    JOB_SPEC is not present, the shell's notion of the current job is
    used.
 
Old 10-01-2006, 10:19 PM   #6
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
You can only put to foreground or background the processes that are child of the current bash. Other programs can't do that. If you disown a process, you'll lose control of it and you can no longer call it as a job. For example

Code:
run &
PID=$!
fg 1
<ctrl-z>
bg 1
disown $PID
# you can't do this anymore
fg 1
If a parent process is sent with a signal and closed, mostly all the child processes are also closed. To prevent the other child processes from being closed, use the disown command.
 
Old 10-07-2006, 11:36 AM   #7
unholy
Member
 
Registered: Sep 2003
Location: Eire
Distribution: Ubuntu 7.10
Posts: 344

Original Poster
Rep: Reputation: 30
Thank you all for that. Even if there were man pages for those commands, they wouldn't be as clear as that.

Best Wishes,
unholy
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration