Admin Essentials

How to script: A Bash crash course

An easy step-by-step guide to the Bash command-line shell and shell scripting

Page 4 of 6

Background processing and job control
Although the shell might seem one-dimensional, in fact you can run many different jobs at the same time. For instance, say you wanted to run a program that you knew would take a long time to complete, and you had other things to do in the shell session in the meantime -- no need to just sit and wait. Rather, tell Bash to run the process in the background. You do this by adding an ampersand after the command line:

[myname@lab1 ~]$ ./longprocess.bin &

[1] 3104

The response below the command is Bash's notification that you've started job No. 1, and its process ID is 3104. The process will continue to run in the background until it completes. When it's done, Bash will let you know:

[1]+  Done     ./longprocess.bin

If you had not added the & when you ran longprocess.bin, you would not get a Bash prompt back until the job completed.

You can bring a background job back into the foreground by using the fg command. Likewise, you can place a foreground job into the background by using the bg command. You can stop a process that's running in the foreground by hitting Ctrl-Z, then place it in the background by entering bg %1:

[myname@lab1 ~]$ ./longprocess.bin

[1]+  Stopped                        ./longprocess.bin
[myname@lab1 ~]$ bg %1
[1]+ ./longprocess.bin
[myname@lab1 ~]$

You can view a list of running jobs by using the jobs command:

[myname@lab1 ~]$ jobs

[1]+  Running                                   ./longprocess1.bin
[2]+  Running                                   ./longprocess2.bin -afG
[3]+  Running                                   ./longprocess3.bin -rT

You can use the fg command to bring one of them back into the foreground:

[myname@lab1 ~]$ fg %1

Note that any output produced by background processes will be shown in the shell, which can get messy if there's a lot of it. Fortunately, we can use our operators to tell Bash to send the output to /dev/null, which will prevent it from displaying in our session:

[myname@lab1 ~]$ ./longprocess1.bin > /dev/null &

This will still show us error messages sent to stderr, but not output sent to stdout. If we wanted to redirect stderr as well, we would type this:

[myname@lab1 ~]$ ./longprocess1.bin > /dev/null 2>&1 &

This tells Bash to send stderr (2) to the same place as stdout (1).

Bash loops
One of the major functions that Bash provides is the ability to run commands in a loop. Loops allow you to quickly perform many functions on a file or set of files or just for general output.

For instance, you might use a loop to systematically and, very quickly, rename a large number of files. Let's say we have a directory full of files like so:


These files have served their purpose, and now we need to rename each of them to Info#.txt.old. Rather than manually typing in each name and using the mv (or move) command, we would be better off using a for loop:

for i in 'ls *.txt'; do mv $i $i.old; done

This is a very simple one-line loop command that will rename all the files ending in .txt to their original name with .old appended at the end. Thus, our files are now named Info1.txt.old, Info2.txt.old, and so forth.

What this loop is doing is using the output of the ls *.txt command as a list of file names, which is represented by the variable $i. Bash will take each file name at a time, then run the mv $i $i.old command, replacing the variable with the actual filename.

| 1 2 3 4 5 6 Page 4
From CIO: 8 Free Online Courses to Grow Your Tech Skills
View Comments
Join the discussion
Be the first to comment on this article. Our Commenting Policies