The Terminal

The Terminal application in Mac OS X lets you send commands or shell scripts directly to the Unix heart of the system. You can also use it to run a huge range of Unix applications, including pine, a text-based e-mail program, and mmap, an application that scans the IP addresses of open ports.

The Terminal window usually displays text with a maximum of 24 lines, each containing up to 80 characters. If you want it to appear in transparent form you should run the application and enter:-

defaults write com.apple.Terminal TerminalOpaqueness 0.4

followed by a press of the Return key.

Shells

The software mechanism that responds to what you enter into the Terminal is known as a shell, of which there are several different varieties. Mac OS 10.3 or higher uses bash (Bourne Again shell), although older versions of the system employ tcsh. The latter is derived from csh (Berkeley Unix C-shell), itself a development of sh (standard Unix Bourne shell). Other variations include ksh (Korn shell) and zsh. Note that in Mac OS X, sh and csh are provided as copies of bash and tcsh respectively, although they operate differently when called by the appropriate name.

Changing Shells

Since bash is superior to tcsh, there’s little point in using a different shell. However, if you’re used to tcsh and want to use it in Mac OS 10.3 or higher, you should enter the following in Terminal and then press Return:-

chsh -s /bin/tcsh username

replacing username by your actual user name. Note that chsh is the command that actually changes the shell.

Permissions

In order to protect itself, the system only allows a valid user to implement some of Terminal’s more dangerous functions. For example, commands that change the ownerships or permissions of files aren’t permitted unless you’re in superuser do (sudo) mode. To get into this state you must be logged-on as an administrator and must start the relevant command lines with sudo, as in:-

sudo <command_line>

where <command_line> should be replaced by real commands. To avoid having to keep typing sudo at the beginning of each line you can enter the following:-

sudo -s

<command_line>

<more_command_lines>

exit

where <more_command_lines> represents any number of lines.

Files and Directories

Terminal can list the files that exist inside a specific directory (folder). To do this you must enter the ‘list’ command, written as ls, followed by an optional - (hyphen) and a letter or string representing the required options and the directory path, if required. As a simple exercise, enter this:-

ls

and then press Return. You should see a list of files in the ‘current’ directory. Now enter:-

ls /

again following it with a Return and noting that a space exists between ls and the / (forward slash). The result should be a list of items at the top level of your drive that aren’t visible in the Finder, including Desktop DB and Classic documents, as well as the invisible bin, cores, dev, etc, mach, mach.sym, mach_kernel, private, sbin, tmp, usr and var files employed in Mac OS X. And of course you’ll see the usual visible items, such as the Applications, Library and System folders.

Further information can be obtained by using the ‘long list’ option, as in:-

ls -l

or by combining this with the ‘all items’ option:-

ls -l -a

which shows all files, including those invisible files identified by names that begin with . (full-stop or period). The order of the option codes isn’t important and they can be grouped, as shown here:-

ls -al

In addition, a listing of items in a particular directory can be obtained, as in:-

ls /Applications

whilst it’s also possible to list items from two folders at once, as in

ls /Users/fred /Users/harry

where the two directory paths are simply separated by a space. A wildcard, represented by the * (asterisk) symbol and indicating any number of characters, can limit the listing, as in this example:-

ls /usr/bin /s*

where the list is restricted to those items whose names begin with the letter s.

The ls command can only be used sensibly in conjunction with the change directory command, which is written as cd and demonstrated in the following examples:-

CommandEffect
cd SitesMoves to ‘Sites’ folder in current directory
cd /Library/WebServer/CGI-ExecutablesMoves to specific location
cd ..Moves one level up from current directory
cd /Moves to root level of Mac OS X
cd ~Moves to home folder
cdMoves to current user’s directory

Once again, you should note the space between cd and the following text. If you get confused, you can also use the print the current working directory to find the current directory:-

pwd

You can obtain further information about a file by entering a line of the form:-

file the_file.php

where the_file.php is the name of the file to be examined. This feature is particularly useful if you have a file that’s been downloaded from the Internet with the wrong filename extension, making it impossible to decompress or decode. Examining it this way lets you determine the kind of coding, allowing you to change the extension accordingly.

Opening Files

Files can be opened directly in Terminal, as in the following examples:-

open /Applications/Calculator.app

open /Users/fred/Pictures

open ~/Pictures

the last two of which have the same effect, assuming that fred is the current user’s home folder.

Copying Files

Terminal can copy files by means of the ditto command, as in this fairly complex example:-

ditto -rsrcFork ~/*.doc /private/temp

where the rsrcFork option ensures that the resource forks of all the files are copied, which may be necessary for some documents. The ~ indicates the user’s home folder and * is the wildcard symbol. Together with .doc, the filename extension for Word documents, this ensures that all such files are copied. Finally, there’s /private/temp, a temporary directory used to store the copied files.

To see if copying was successful you can select Go ➡ Folder and enter /private/temp or you can type the following into the Terminal window:-

cd /private/temp

ls

which should show the copied items.

Removing Items

A file can be removed by typing a line of the following form:-

rm -f ~/the_unwanted_file.txt

and then pressing Return. Note that the f option indicates that a file is to be removed. You can also enter

rm -f

ensuring that it ends with a space, and then drag the unwanted file into the window. This causes its path to appear, allowing you to press Return to initiate the operation. Removing a folder is trickier, since all of the subfolders and other items within it must be removed, requiring the recursive operator, which is indicated by the R code in the following example:-

rm -R ~/the_unwanted_folder

In the same way as with files, you can enter

rm -R

and then drag the offending folder into the window and press Return.

The following line removes all the folders in your home folder whose names begin with Old:-

rm -R ~/Old*

If you have problems removing a particular item from the Trash you can try entering

cd Trash

ls

sudo rm -R <item_name>

The first line changes the current directory to the Trash, the second line lists the content and the third removes the offending item, whose name should be entered in place of <item_name>.

Editing Files

You can use text editors such as emacs, pico and vi to modify text files. Unlike normal Mac OS text applications, such as TextEdit, these editors can be used on invisible files, all of which begin with a . (full stop or period). The most common editor, and the only one found in all versions of Unix, is vi, which you can use by entering the following:-

vi the_file.txt

where the_file.txt must be replaced by the name of the file you want to edit.

Changing Settings

The Terminal also lets you modify various settings, including many that can’t be changed in the standard panes of System Preferences. The information for these is usually found in special text files that reside in the /Library/Preferences or ~/Library/Preferences folders. Each file, normally identified by a .plist filename extension, contains an XML property list that defines the settings. Although these can be modified using Apple’s Property List Editor, as supplied with the system, or by means of a standard text editor, they can also be changed directly from within Terminal. Some examples are given below.

Anti-aliasing

The anti-aliasing effect employed in Mac OS X can be disabled by entering

sudo defaults write CoreGraphics CGFontDisableAntialiasing yes

although the results often look even worse.

The Dock

A hidden application in the Dock normally looks exactly the same as one that’s active. This state of affairs is set within a file entitled com.apple.Dock.plist and can be changed by entering

defaults write com.apple.Dock showhidden -bool yes

and pressing Enter, which makes any hidden applications appear semi-transparent. However, to make this effective you must first restart the Dock application, which you can do from within the Activity Monitor application (or Process Monitor in older systems): simply click on Dock in the processes list and choose Process ➡ Quit.

Parameter RAM (PRAM)

The contents of the PRAM, which is really a non-volatile RAM (NVRAM), can be modified from within Terminal, as shown in this example:-

sudo nvram boot-args="romndrv=1"
Apparently, this instruction can re-activate a second monitor, should it fail to work after upgrading to Mac OS X 10.3. Having done this, you should restart the computer, although it may then fail to start, in which case you must clear the PRAM by holding down -P-R, starting the machine and holding down the keys until you hear three chimes. This illustrates the possible dangers of using the Terminal.

Web Site Names

The system allows each user of a machine to have a Web site with a URL of the form

http://xxx.xxx.xxx.xxx/~username

where xxx.xxx.xxx.xxx represents the numerical IP address of the machine and username is replaced by the user’s short name. The need to use ~ in the address can be avoided as described here. First, run Terminal and type

cd/etc/httpd/users

followed by a Return. You can now enter ls and press Return to see the configuration files for the users’ Web sites, as identified by .conf filename extensions. Assuming there’s an appropriate username.conf file, enter

sudo pico username.conf

and press Return. This leads you into the pico file editor, where you must enter the following above the top line:-

Alias /username "/Users/username/Sites"

which means that the Apache server in Mac OS X will point any enquiries addressed to http://xxx.xxx.xxx.xxx/username to the appropriate Sites folder. Having done this, press Ctrl-X to exit the editor and press Y to confirm saving of the file. To make the change effective, you must turn off Personal Web Sharing in the Sharing pane and then turn it on again.

Other File Operations

The content of files can be extracted using commands such as tail, head, more, less and cat. In addition, a new directory can be created using mkdir or a file updated using the touch command.

Prior to changing something relating a file, you may first have to modify its ownerships or permissions settings using commands such as d, chmod, chown and chgrp. Here’s an example:-

sudo chown fred the_file.htm

which changes the owner’s name of the_file.htm in the current directory to fred.

Files can be unlocked using one of the following:-

chflags -R noschg <item_name>

chflags -R nouchg <item_name>

sudo chmod 777 <item_name>

where <item_name> must be replaced by the real name of the item.

At a more complex level, you can make the printenv and test-cgi CGI scripts contained in /Library/WebServer/CGI-Executables into executable files by entering:-

sudo chmod a+x printenv test-cgi

which also shows how two files can be modified on the same line. These files can then be run from within your Web browser, assuming Web Sharing is enabled, by entering addresses of http://localhost/cgi-bin/printenv and http://localhost/cgi-bin/test-cgi.

Changing End-of-Line Characters

By tradition, the Mac OS uses a carriage return (CR) code for line endings, whilst Unix employs a new line or line feed (LF) code. Unfortunately, CR codes can be a problem in text files used as an input into HTML pages or in scripts employed with the Apache Web server software. To see if a file contains these characters you can invoke the vi text editor by typing:-

vi the_file.txt

where the_file.txt is replaced by the name of your file. Each occurrence of ^M in the result shows a CR code, since this is also produced by pressing Ctrl-M. To convert these to LF codes (^N or Ctrl-N) you can enter the following:-

perl -pi -e 's/\r\n?/\n/g' the_file.txt

where perl is the scripting language, -pi indicates every line is to be processed, -e means this is to be run as a script, s tells it to substitute the characters, / denotes the beginning of the search string, \r\n? is the search string itself (the \r being a CR and the \n being a LF), / marks the start of the replacement string, \n is the new LF and g indicates that the operation is global.

Converting Image Files to Icons

The default icon for an application is kept in the appropriate application package (.app), as shown here for GarageBand:-

GarageBand.app/Contents/Resources/GarageBand App.icns

where GarageBand App.icns can be replaced by an alternative icon, if preferred. A suitable image, which can be created as a TIFF document, can be converted into the required .icns format by entering:-

tiff2icn

pressing Space, dragging the TIFF document into the window and pressing Return.

Speech

The Text-to-Speech (TTS) abilities of Mac OS X can also be used from within Terminal, as in

say "hello" -v Junior

which produces the word hello using the voice called Junior, although you can leave out the -v and the voice name to use the default voice. You can also make Terminal read out the content of a text file. In the following example the spoken result is converted into into an AIFF sound file:-

say -f text_file.txt -o sound_file.aiff
where text_file.txt is the name of the text file and sound_file.aiff is the name of the new file containing the sound recording.

Redirection, Pipes and Data

In common with other command line interfaces, Terminal can redirect the output of one instruction to the next by means of a pipe, as represented by a | symbol and shown in the following example.

ls-l|more

which pauses each full screen of data as it appears. Enclosing commands within ` (backtick) characters directs data from the result of one command to another, as in:-

cd `cat directory_file.txt`

where directory_file.txt is a file containing the path to a directory and the cat command returns the contents of anything that follows. As a result, Terminal moves to the directory specified in the file.

You can also dump data to a file using the > command, as in:-

ls -l ~ > ~/list_file.txt

This example makes a list of the files in the users home folder and dumps it to a file called list_file.txt in the same folder. Note that the > symbol points in the direction of transfer. The text file is created if it doesn’t exist, but if already present the existing content is overwritten. The following line is similar, except that the data is appended to an existing file.

ls -l ~ >> ~/list_file.txt

Appending data to a file is more useful, however, when used to create a log file, which records information about certain events. The next example keeps a running log of your machine’s ‘uptime’:-

uptime >> uptime_log.txt

Using the find command along with the print option lets you create a file containing a list of items that meet a specified criteria. The following lists the MP3 files in your Music folder, these being identified by .mp3 filename extensions.

find ~/Music -iname "*.mp3" -print > tunes_list.txt

Pipes can also be used for processing archives. For example, you may want open a tape archive, also known as a .tar file. These files are often compressed using Gzip and may therefore carry .tar and .gz filename extensions. The following line ‘untars’ and ‘gunzips’ such a file in a single pass.

tar -zxvf the_file.tar.gz

whilst this variation uses a pipe to firstly ‘gunzip’ the file and then ‘untar’ it:-

gzip -dc the_file.tar.gz | tar -xvf

A Complex Example

The following, as created by Greg Knauss, demonstrates the power of Terminal:-

find ~-name '*.doc' | cpio-o | gzip > `date +~/%Y%m%d.cpio.gz`

The phrase find ~-name '*.doc' locates all the files in the home folder whose names end in .doc. These are fed to cpio, the ‘copy input/output’ command, with -o indicating that an output archive is to be created. This, in turn, is directed to gzip, which applies the compression of the same name, the result of which is directed to a single file in the home directory. This file is named according to the current date in YYYYMMDD format and is given a double filename extension of .cpio.gz.

An individual file can be retrieved from the archive by using the line:-

gzip -d -c YYYYMMDD.cpio.gz | cpio -i -d -r '*file_name*'

where YYYYMMDD.cpio.gz is the name of the archive and file_name is the name of the single document that you want to extract. To restore any one of the files via a prompt you can use:-

gzip -d -c YYYYMMDD.cpio.gz | cpio -i -d -r

or you can expand the entire document using;-

gzip -d -c YYYYMMDD.cpio.gz | cpio -i -d

Unix Aliases and Links

A Unix alias, not to be confused with a normal Mac OS alias, lets you enter a shortcut instead of a long string of commands. Typing the following creates a shortcut of wd, which changes the current directory to your Web server documents folder:-

alias wd 'cd /Library/WebServer/Documents'

Having done this, typing wd will move you directly to this location. However, such an alias is lost once you close Terminal’s window. To make an alias permanent you must save the information in one of the invisible files that are recognised by your particular shell. The files employed by bash, in order of searching, are ~/.bash_profile, ~/.bash_login and ~/.profile. Since bash disregards any of the subsequent files it’s best to store aliases and other information in ~/.bash_profile.

To save the alias information in a particular file you must employ a Unix text editor, one of the most common being pico. To create the above shortcut requires you to enter:-

pico .bash_profile

followed by:-

alias wd 'cd /Library/WebServer/Documents'

after which you must press Ctrl-O and Return to save the file and Ctrl-X to exit from pico. Having done this, you can confirm the existence of your alias in the ~/.bash_profile file by entering:-

source .bash_profile

You can then press wd to see if your shortcut actually works.

Symbolic Links

Unlike an alias, a symbolic link effectively redirects a folder. For example, supposing one of your home folders is at:-

/Users/fred

Then you can force the system to look for the fred folder on a drive called Big Drive in a folder named Data by entering:-

ln -s /Big Drive/Data/fred /Users

For this to work, you must, of course, copy the original fred folder to the required location.

Manuals

Mac OS X incorporates the full documentation for the Unix operating system, all of which can be obtained using the man command. For example, the following lines:-

man netinfo

man ftp

man perl

man perlrequick

provide the NetInfo Manager manual, FTP information, the Perl manual and a quick look at Perl respectively. If preferred, you can convert the information provided by a particular man command into a PostScript file, complete with boldface text and formatting, which can be viewed in Apple’s Preview application. The following lines in Terminal convert the quick reference document for the Perl language into such a file and opens the result in Preview:-

man -t perlrequick > /tmp/perlrequick.ps

open /tmp/perlrequick.ps

In this instance, the /tmp folder has been chosen, which is cleared automatically the next time your computer is started. You should choose a different location if you want to retain the file indefinitely.

Other Operations

System information can be obtained using commands such as df, domainname, hostname, machine and who, whilst processes can be determined using ps and top. You can also check if other computers are communicating with your machine over a network by entering a line of the form

netstat -na | grep 548

Using the Clipboard

The pbcopy and pbpaste commands let you copy and paste data to and from the Mac’s clipboard. For example, the line

ls -al|pbcopy

pipes the result of the ls -al listing to the clipboard, whilst the following line

pbpaste > list.txt

pastes the contents of the clipboard into a new text file named list.txt.

Working with AppleScript

The Terminal can also be used to send messages that conform to the rules of Open Scripting Architecture (OSA), as used in AppleScript. Here’s an example:-

osascript -e 'set volume 10'

where the text in quotes is standard AppleScript scripting. The following example uses the Mac’sspeech system:-

osascript -e 'say "I am speaking these words" '

Note that double quotes are used to distinguish the speech element of the command.

Updating Software from a Remote Computer

You can tell a remote machine connected via a network to receive an Apple software update. First, type the following:-

sudo softwareupdate

which should reveal a list of the available and appropriate updates. Having determined the required update you should enter the following:-

sudo softwareupdate update_name

where update_name must be replaced by the name of the update, as shown in the list.

Blocking a Web Site

Access to a particular Web site location can be blocked by redirecting your browser to your own machine’s pages, as implemented by a line of the following form:-

sudo sh -c 'echo "127.0.0.1 sitename.org" > > /etc/hosts

This appends the text in single quotes to the /etc/hosts file (the top-level folder of which is invisible). To undo this you must edit this document using pico or a similar text editor. Simply type

sudo pico /etc/hosts

and delete the line containing the site. Then press Ctrl-O and Return to save the file and Ctrl-X to exit pico. Having done this you may need to restart the computer.

The Calendar

The command cal shows a monthly calendar. The names of the days can be changed, as in the following example, which provides French names. Note that there are two spaces in front of any original names that only have one character.

alias cal "cal / sed 's/ Su  M Tu  W Th  F  S/Di Lu Ma Me Je Ve Sa/'"

This change can be made permanent by saving the alias to an appropriate file, as described above.

Terminal and Scripts

Support for the Perl and other scripting languages is built into Mac OS X. Script of these kinds can be easily created using a suitable text editor, such as BBEdit.Here’s an example that converts line endings in a file from Mac to Unix format. Note that all variable names start with a $ (dollar symbol) and arrays begin with @ (commercial ‘at’ or ‘comat’), whilst comments begin with a # (number symbol or ‘hash’) and end with a \ (backslash).

#!/usr/bin/perl -w

# linebreak characters:\x0d - Mac, \x0a - Unix

{

    for each in $inFileName (@ARGV) {

        open (INTEXTFILE, $inFileName);

        open (OUTTEXTFILE, ">".$InFileName.".converted");

        $theText=<INTEXTFILE>;

        $theText=~s/\x0d/\x0a/;

        print OUTTEXTFILE $theText;

        close (INTEXTFILE);

        close (OUTTEXTFILE);

}

The file containing this script should be given a name such as lineconvert.pl. In Terminal, set the script’s attributes by moving to the appropriate directory and entering chmod 744 lineconvert.pl. To run the script, type ./lineconvert.pl mac.text, where mac.text is replaced by the name of the source file, giving the new file a name in the form of mac.text.converted.

The Script in Detail

Here’s a quick break-down of the script itself. First of all, there are two comment lines

#!/usr/bin/perl -w    

# linebreak characters:\x0d - Mac, \x0a - Unix

where -w indicates that warnings are to be given for suspect code. The line

for each in $inFileName (@ARGV) {

starts a repeat loop that encloses much of the script, taking source filenames from the @ARGV array and placing them in turn into the variable called $inFileName. The line

open (INTEXTFILE, $inFileName);

opens the file and refers to it as INTEXTFILE. A new file, referred to as OUTEXTFILE, is created using

open (OUTTEXTFILE, ">".$InFileName.".converted");

which gives it the same name as the original, but with an extension of .converted. The next two lines

$theText=<INTEXTFILE>;

$theText=~s/\x0d/\x0a/;

read the text from INTEXTFILE (which must be less than 100 KB in length) to a variable called $textFile and uses s (search and replace) to change the line endings as required, where ~ causes the the result to be placed in the same variable as the original text. Finally, in these lines

print OUTTEXTFILE $theText;

close (INTEXTFILE);

close (OUTTEXTFILE);

the content of $theText is ‘printed’ to OUTTEXTFILE and both files are closed.

Using the Unix Console

Apart from Terminal, you can also get your Mac to behave as an original Unix machine, allowing you to send shell instructions outside of the Mac OS. To do this, select Log Out and then log in again using the name <console and a blank password. If a list of users appears you should select Other (if this isn’t there you should select another user and then add Other to the list and try again).

At this stage you should see login:, after which you should enter the short name of your user account. Having done this, you’ll see the standard Unix prompt, allowing you to enter commands such as ls and the others described above. Once you’ve finished, type exit and press Return.

References

Command Line, Greg Knauss, MacWorld magazine (UK), IDG Communications, May 2003

Mac OS X Bible, Panther Edition, Sam A Litt, et al, Wiley Publishing Inc, 2004

MacWorld magazine (UK), IDG Communications, 2002-2004

©Ray White 2004.