CHAPTER 2

image

Working in the Shell

Every Linux/Solaris system includes at least one command-line interpreter that enables you to interact with the OS. This interpreter is known as a shell. It is an appropriate moniker because the shell’s purpose is to act as a layer that shields you from having to know the internal workings of the OS. The shell allows you to perform complex tasks using simple commands.

If you’re a DBA, you should know how to run shell commands from the command line (OS prompt). Yes, you can perform many DBA tasks through various GUIs, but regardless of the robustness of the GUI, you still have to use the command line to perform tasks that the GUI can’t handle. For example, you might be in a stressful database restore-and-recovery situation in which you have access only to a terminal to run the appropriate commands. In this scenario, your job depends on being able to work from the command line to diagnose possible media failures and then perform the appropriate database restore-and-recovery operations.

There are many command-line interpreters available (the Bourne Again (Bash) shell, Korn shell, C shell, and so on). Because the Bash shell is usually the default command-line interpreter on many systems, the focus of this chapter (and this book, for that matter) centers on how to perform DBA tasks using the Bash shell. We strongly encourage you to use the Bash shell as your default command-line interpreter because it incorporates most of the useful features of other available shells and provides additional functionality. Where appropriate, we’ll also juxtapose key features of the Bash shell with both the Korn shell and C shell.

When you log on to your database server, you are “in” a shell, which means that you can enter commands that the shell will interpret and run for you. The most common default shell prompt is the $ (dollar sign) character, so most examples in this book denote the shell command line with the $ character. Here’s an example:

$ <commands run here>

Image Note  The # (hash) is used for the prompt to denote operations that need to be performed as the root user.

This chapter covers topics such as obtaining information about the shell environment and customizing it. The solutions will enable you to work efficiently at the command line on database servers. The command line is where you will perform most of your database administrator activities.

Because a typical DBA spends several hours per day using commands at the shell prompt, the shell is a tool that all DBAs must thoroughly understand. The solutions in this chapter will form the building blocks for the more complex DBA tasks covered in the rest of this book.

2-1. Displaying the Current Shell

Problem

You want to verify which shell you are currently using.

Solution

When you first log on to a server, you can verify the default shell viewing the value of the SHELL variable. You must specify a $ in front of the variable to display its contents:

$ echo $SHELL

In this example, the output indicates that the Bash shell is in use:

/bin/bash

Many of the recipes in this chapter require the use of the Bash shell. What if the prior output showed that you were using a shell other than the Bash shell? For example, suppose that you view the value contained in $SHELL, and it indicates that your default shell is the C shell after first logging in:

$ echo $SHELL
/bin/csh

In this situation, to enter a Bash shell session type in the bash command, use the following:

$ bash

The prior command does not change your default logon shell, so the value of SHELL remains unchanged. However, you can use the $0 variable to show your current working shell. The $0 variable holds the name of the shell or script that is currently running. The following command verifies that the current working shell has been changed to the Bash shell:

$ echo $0
bash

In this situation, to exit out of the Bash shell session, type the exit command, which returns you to the parent session:

exit

Image Tip  See recipe 2-13 for details on changing your default logon shell.

How It Works

You might occasionally be logged on to a box and wonder why certain Bash shell commands aren’t working. This is most likely because your default logon shell is not the Bash shell. In shops that have a large number of Linux/Solaris servers, there might not be a consistent shell used as a common standard. In these types of environments, first verify the default logon shell in use by displaying the contents of the SHELL variable. As shown in the solution section of this recipe, you can modify the current working shell by entering in the name of the shell you want to enter.

Image Note  On Linux boxes, you can verify which shells are available by viewing the contents of the /etc/shells file. This file isn’t a standard file on Solaris systems, but it can be created by the system administrator.

Another method for viewing the current shell is to run the ps command without any options:

$ ps

The first line of the output shows which shell you are currently using. You should see output similar to this:

PID  TTY       TIME     CMD
9088 pts/1     00:00:00 bash
9137 pts/1     00:00:00 ps

If you enter a shell from a shell (e.g., from the C shell to the Bash shell), you should see all shells in use in the output. The following example demonstrates this. First verify your default shell:

$ echo $SHELL
/bin/csh

Next, enter the Bash shell:

$ bash
$ echo $0
bash

Now view the process status:

$ ps
  PID TTY          TIME CMD
 1521 pts/13   00:00:00 csh
 5944 pts/13   00:00:00 bash
 5951 pts/13   00:00:00 ps

When the ps command is used without any parameters, it displays all processes associated with the current user and terminal. So you might see more processes, depending on which commands you executed in the current session.

Image Tip  On Linux boxes, use the pstree command to view the hierarchical relationship of processes. On Solaris systems, use the ptree command to view process ancestry.

2-2. Running Previously Entered Commands

Problem

You are spending a lot of time retyping commands that were previously entered. You want to view, edit, and rerun shell commands that were recently executed.

Solution

One timesaving feature of the Bash shell is that it has several methods for editing and rerunning previously executed commands. This bulleted list highlights several options available for manipulating previously typed commands:

  • Scrolling with the up and down arrow keys
  • Using Ctrl+P and Ctrl+N
  • Listing command history
  • Searching in reverse
  • Setting the command editor

Each of these techniques is described briefly in the following sections. Keep in mind that some of these techniques might not be available, depending on the OS version.

Scrolling with the Up and Down Arrow Keys

Use the up arrow to scroll up through your recent command history. As you scroll through previously run commands, you can rerun a desired command by pressing Enter or Return.

If you want to edit a command, use the Backspace key to erase characters or use the left arrow to navigate to the desired location in the command text. After you have scrolled up through the command stack, use the down arrow to scroll back down through previously viewed commands.

Image Note  If you’re familiar with Windows, scrolling through the command stack is similar to the DOSKEY utility.

Pressing Ctrl+P and Ctrl+N

The Ctrl+P keystroke (pressing the Ctrl and P keys at the same time) displays your previously entered command. If you have pressed Ctrl+P several times, you can scroll back down the command stack by pressing Ctrl+N (pressing the Ctrl and N keys at the same time).

Listing Command History

Use the history command to display commands that have been previously entered by the user:

$ history

Depending on how many commands have previously been executed, you might see a lengthy stack. You can limit the output to the last n number of commands by providing a number with the command. For example, the following lists the last five commands that have been run:

$ history 5

Here is some sample output:

273  cd -
274  grep -i ora alert.log
275  ssh -Y -l oracle 65.217.177.98
276  pwd
277  history 5

To run a previously listed command in the output, use an exclamation point (!, sometimes called the bang) followed by the history number. In this example, to run the pwd command on line 276, use ! as follows:

$ ! 276

To run the last command you ran, use !!, as shown here:

$ !!

Searching in Reverse

Press Ctrl+R (press the Ctrl and R keys at the same time), and you’ll see the Bash shell reverse search utility:

$ (reverse-i-search)`’:

As you type each letter from the reverse-i-search prompt, the tool automatically searches through previously run commands that have text similar to the string you entered. As soon as you see the desired command match, you can rerun the command by pressing Enter or Return. To view all commands that match a string, press Ctrl+R repeatedly. To exit from the reverse search, press Ctrl+C.

Setting the Command Editor

You can use the set -o command to make your command-line editor to be either vi or emacs. This example sets the command-line editor to be vi:

$ set -o vi

Now when you press Esc+K, you are placed in a mode in which you can use vi commands to search through the stack of previously entered commands.

For example, if you want to scroll up the command stack, you can use the K key and you can scroll down using the J key. When in this mode, you can use the slash (/) key and then type a string to be searched for in the entire command stack.

Image Tip  Before you attempt to use the command editor feature, ensure that you are thoroughly familiar with either the vi or emacs editor (see Chapter 4 for details on using vi).

A short example illustrates the power of this feature. Suppose that you know you ran the ls -altr command about an hour ago. You want to run it again, but this time without the r (reverse sort) option. To enter the command stack, press Esc+K:

$ Esc+K

You should now see the last command you executed. To search the command stack for the ls command, type /ls and then press Enter or Return:

$ /ls

The most recently executed ls command should appear at the prompt:

$ ls -altr

To remove the r option, use the right arrow key to place the prompt over the r on the screen and press X to remove the r from the end of the command. After you edit the command, press Enter or Return to have it executed.

How It Works

Your command history is a stored sequential list of all the commands you have previously entered. You can use any of the techniques described in the “Solution” section of this recipe to view and manipulate previously entered commands.

The Bash shell command history is stored in your home directory in a file named .bash_history. If your current working directory is your home directory, you can view the contents of this file with a utility such as cat. The following example uses the cd command to navigate to the home directory and then displays the contents of the .bash_history file with the cat command:

$ cd
$ cat .bash_history

The number of entries stored in the .bash_history file is determined by the HISTSIZE OS variable. You can verify the history size using the echo utility. On this system, the command history size is 1000:

$ echo $HISTSIZE
1000

System administrators usually set the HISTSIZE variable in the /etc/profile file, which is automatically executed whenever a user logs on to a server. You can override the system’s default value for command history by setting the HISTSIZE variable in a special startup file (see recipe 2-5 for details).

The easiest way to view the Bash shell command history is to use the up and down arrows to find the command of interest, and use the left and right arrows and/or the Backspace key to modify the command. Other shells typically do not allow the use of the up and down arrows.

Table 2-1 lists some common shells and what types of command history manipulation each tool supports.

Table 2-1. Command History Options Available in Each Shell

Table2-1

2-3. Automatically Completing Long Commands

Problem

You are tired of typing long commands and wonder whether there is some way the Bash shell can automatically fill in the text for long command strings.

Solution

The Tab key can be used for command completion. For example, suppose that there are two files in the current directory: initRMOUGDB.ora and initBRDSTN.ora:

$ ls
initBRDSTN.ora initRMOUGDB.ora

In this example, you want to edit the initRMOUGDB.ora file with the vi utility. All you have to do is type enough characters to make the file name unique within a directory and then press Tab (ensure that there is no space between the text and the Tab key):

$ vi initR<Tab>

Because there are no other files in the current directory that begin with the string initR, the Bash shell automatically fills in the text initRMOUGDB.ora:

$ vi initRMOUGDB.ora

Now you can press Enter or Return to edit this file. Note that you can use this technique on any program, directory, command, or file. For example, if you need to change directories to a subdirectory named products, and there are no other directories beneath your current working directory that start with the letter p, you can type cd p and then press Tab. Your prompt then shows the following:

$ cd products/

You can now press Enter or Return to execute the cd products command.

How It Works

A timesaving feature of the Bash shell is command completion, which allows you to only partially type a program, command, file, or directory. You then press Tab, and the shell attempts to complete the rest of the text.

If the Bash shell can’t uniquely identify a program, command, file, or directory, it beeps (or does nothing) after you press Tab. In this situation, if you press Tab again, the shell displays all the possible programs, commands, files, or directories that match the partially typed string.

For example, command completion can be used to show all executable files that start with a certain string. If you want to view all commands that start with the string di, type di and press Tab twice:

$ di<Tab><Tab>
diff        diff-jars  dir        dirname    disable    disown
diff3       dig        dircolors  dirs       disol

You might hear a bell or beeping sound after you enter the first Tab. The Bash shell will search for commands that start with the string di that are located in any directories contained within the PATH variable.

2-4. Viewing Environment Variables

Problem

You want to view the current settings of your environment variables.

Solution

You can use any of the following Linux/Solaris commands to display OS variables:

  • printenv
  • env
  • set
  • export
  • echo

To display all variables set in your environment, use any of these commands (without any options): printenv, env, set, or export. The next bit of code uses the printenv command to show all environment variables:

$ printenv

Here’s a partial listing of the output:

HOSTNAME=rmg.rmg.org
TERM=cygwin
SHELL=/bin/bash
HISTSIZE=1000
SSH_TTY=/dev/pts/0
USER=oracle

If you know the name of the variable you want to display, you can display it directly with the echo command. To display the contents of an OS variable, you must preface it with a $ (dollar sign) character. This example uses the echo command to display the contents of the USER variable:

$ echo $USER
oracle

You can also use the printenv command to display environment variables. The following example uses printenv to show the current setting of the USER variable:

$ printenv USER
oracle

How It Works

Most DBAs work with multiple database servers. Every time you log on to a server, certain OS variables are automatically set for you. Table 2-2 lists several environment variables you should know. Use any of the commands described in the “Solution” section of this recipe to view variables in your environment.

Table 2-2. Commonly Used Environment Variables

Variable

Description

PATH

Contains a list of directories in which the shell looks to find the executable commands. This variable is usually set by a shell startup script.

USER or LOGNAME

Contains the user account you used to log on to the server. It is automatically set for you when you log on.

HOME

Holds the home directory for a user. It is set for you when you log on.

~

Holds the home directory for a user. The tilde character is a shorthand way to reference your home directory. It is set for you when you log on.

PWD

Contains the location of the current working directory. It is set whenever you use cd to navigate to a new directory.

SHELL

Contains the name of your login shell.

EDITOR

Holds the name of the default editor used with some utilities (such as cron).

PS1

Contains the values used for displaying the command prompt.

SHLVL

Keeps track of how many subshell levels deep your current shell is.

DISPLAY

Is used by X applications to determine the display server used for input and output.

Sometimes you might not know the exact name of the variable. You can use the grep command to filter the output. This example uses the set command and sends the output to the grep command for filtering any variables:

$ set | grep ORA

Here’s typical output from the previous command:

ORACLE_BASE=/oracle
ORACLE_HOME=/oracle/product/10.2
ORACLE_SID=RMDB1
PS1=’[h:u:${ORACLE_SID}]$ ’

Image Tip  For details on all variables set by the Bash shell in your environment, inspect the output of the man bash command. Search the man page for the Shell Variables section.

2-5. Automatically Setting Shell Variables

Problem

You want to automatically set various database variables whenever you log on to the database server.

Solution

Place shell variables that you want automatically set (when you log on) in the .bash_profile file in your home directory. In the next example, the ORACLE_SID variable is set to BRDSTN. The following text is placed in the .bash_profile file:

export ORACLE_SID=BRDSTN

If you log off and log back on, you can verify that this variable has been set by echoing it:

$ echo $ORACLE_SID
BRDSTN

If you don’t want to log off and back on, run the file manually using the . (dot) command, which executes the lines contained within a file. The following example runs the .bash_profile file:

$ . $HOME/.bash_profile

The . (dot) instructs the shell to source the script. Sourcing tells the shell process that you are currently logged on to inherit any variables set with an export command in an executed script. If you don’t use the . (dot) notation, the variables set within the script are visible only within the context of the subshell that is spawned when the script is executed.

Image Note  In the Bash shell, the source command is equivalent to the . (dot) command.

How It Works

When you use the Bash shell, several special startup files can be executed for you when you first log on to your database server:

  • /etc/profile
  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile

Image Note  Depending on the version of the Linux/Solaris OS, there might be different startup files in use. Run the ls -altr command in your home directory to view all the available files. Files beginning with a dot are sometimes referred to as hidden files and don’t appear in the output of the ls command when it is used with no arguments.

The /etc/profile file is maintained by your system administrator, and you need root privileges to modify it. This file sets systemwide variables common to all users logging on to the system. Here is a snippet of some typical entries in the /etc/profile file:

# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
# Set OS variables
USER="`id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
HOSTNAME=`/bin/hostname`
HISTSIZE=1000

After running the /etc/profile file, the Bash shell next searches for the following files and runs only the first file it locates (in the following order): ~/.bash_profile, ~/.bash_login, ~/.profile.

Here are some typical entries in the oracle user’s ~/.bash_profile file:

# User specific environment and startup programs
export ORACLE_SID=O1212
export ORACLE_HOME=/u01/app/oracle/product/12.1.0.2/db_1
export PATH=$PATH:$ORACLE_HOME/bin
PS1=’[h:u:${ORACLE_SID}]$ ’

You should be aware of two additional important startup type files:

  • ~/.bashrc
  • ~/.bash_logout

If you start a nonlogin Bash shell by typing bash at the command line, the ~/.bashrc file is automatically executed for you. DBAs place commands in ~/.bashrc to ensure that database–related OS commands are consistently set, regardless of whether they are using a login shell or a nonlogin shell. A common technique to address this is to place the following code in the ~/.bash_profile file:

# Run .bashrc if it exists
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

When first logging on to a server, the previous bit of code checks to see whether the ~/.bashrc file exists; if so, it runs it. This method ensures that aliases and functions are defined in a consistent manner, regardless of whether it is a login or nonlogin shell.

The ~/.bash_logout file is appropriately named and is executed when you issue the exit command. Typically, you might see the clear command executed in the ~/.bash_logout file to clear text off the terminal when logging out.

2-6. Customizing the Command Prompt

Problem

You work with several database servers and usually have several terminal screens open simultaneously on your screen. To avoid confusion, you want the hostname and username to display in the command prompt.

Solution

In the Bash shell, the special OS variable PS1 holds the text string of what appears in the command prompt. This example changes the PS1 variable to hold the hostname and username:

PS1=’[h:u]$ ’

The h and u variables are special Bash variables that hold the hostname and username, respectively. After setting PS1 in this example, the prompt now shows the following:

[rmougprd1:oracle] $

In the prior string, rmougprd1 is the hostname, and oracle is the current OS user. You can also combine special variables and user-defined variables to be displayed in the prompt. For example, the following combination contains current hostname, username, and database SID:

PS1=’[h:u:${ORACLE_SID}] $ ’

Here’s what the command prompt looks like now:

[rmougprd1:oracle:ORA12CR1] $

If you place the previous line of code in your .bashrc startup file (see recipe 2-5 for details), your prompt will automatically be set to contain hostname, OS user, and the current value of ORACLE_SID every time you log on to the server or start a new Bash shell. Additionally, if you change the value of ORACLE_SID, your prompt will automatically reflect the new setting.

How It Works

Setting your command prompt to something informational can be invaluable for DBAs who work with multiple servers, OS accounts, and databases. If you work in complex environments, this simple technique will keep you aware of your current surroundings.

Image Tip  You can view all variables available in your environment by issuing a man bash command. Search for PROMPTING in the man page.

Table 2-3 lists many of the Bash shell backslash–escaped special variables that you can use to customize your command prompt.

Table 2-3. Bash Shell Backslash–Escaped Variables Used to Customize the Command Prompt

Variable

Description

a

ASCII bell character.

d

Date in “weekday month date” format (for example, Thu Aug 21).

e

ASCII escape character.

h

Hostname.

j

Number of jobs managed by shell.

l

Base name of shell’s terminal device.

Newline.

Carriage return.

s

Name of shell.

Time in 24-hour HH:MM:SS format.

T

Time in 12-hour HH:MM:SS format.

@

Time in 12-hour a.m./p.m. format.

A

Time in 24-hour HH:MM format.

u

Current username.

v

Version of Bash shell.

V

Release of Bash shell.

w

Current working directory.

W

Base name of current working directory.

!

History number of command.

$

If effective UID is 0, display #. Otherwise, display $.

2-7. Creating a Command Shortcut

Problem

You frequently retype long sets of commands and want to create a shortcut to the lengthy commands.

Solution

There are two very common methods for creating shortcuts to other commands: aliases and functions. These two techniques are described in the following sections.

Using an Alias

Suppose that you often navigate to a database background process logging destination to view log files. You have to type something similar to this:

$ cd /u01/app/oracle/diag/rdbms/o1212/O1212/trace

You can use the alias command to create a shortcut to accomplish the same task. This example creates an alias named ad (alert directory) that will change directories to a background location that is dependent on the value of the ORACLE_SID variable:

$ alias ad=’cd /u01/app/oracle/diag/rdbms/o1212/O1212/trace’

Now you can type ad, which is the same as changing your current working directory to the Oracle background dump directory.

Using a Function

You can also use a function to create command shortcuts. We provide only a brief example of how to use a function in this recipe; for full details on using functions, see Chapter 7. The following line of code creates a simple function named ad:

$ function ad { cd /u01/app/oracle/diag/rdbms/o1212/O1212/trace; pwd;}

You can now type ad at the command line to change your working directory to the Oracle background dump directory. Notice that the current working directory is displayed by the pwd command after you change directories.

How It Works

An alias is a simple mechanism for creating a short piece of text that executes other shell commands. To show all aliases that have been defined, use the alias command with no arguments:

$ alias

Listed here are some common examples of alias definitions that DBAs use:

alias l.=’ls -d .*’
alias ll=’ls -l’
alias lsd=’ls -altr | grep ^d’
alias ad=’cd /u01/app/oracle/diag/rdbms/o1212/O1212/trace’
alias sqlp=’sqlplus "/ as sysdba"’
alias shutdb=’echo "shutdown immediate;" | sqlp’
alias startdb=’echo "startup;" | sqlp’
alias valert=’view /u01/app/oracle/diag/rdbms/o1212/O1212/trace/alert_O1212.log’

Depending on your implementation of Oracle’s Optimal Flexible Architecture (OFA) standard and the version of Oracle, you have to modify some of the previous alias definitions. This is especially true in regard to the location of the alert.log file.

If you want to view a definition for a particular alias, use the following:

$ alias ad
alias ad=’cd /u01/app/oracle/diag/rdbms/o1212/O1212/trace’

You can also use the type command to verify an alias:

$ type ad
ad is an alias for ’cd /u01/app/oracle/diag/rdbms/o1212/O1212/trace’

If you want to remove an alias definition from your current environment, use the unalias command. The following example removes the alias for ad:

$ unalias ad

The unalias command affects only your current connection. Although using aliases is a common way to create command shortcuts, we recommend using functions over aliases. Functions are more powerful because of features such as the ability to operate on parameters passed in on the command line and can contain multiple commands.

Functions are described in much more detail in Chapter 7, but we’ll take a few minutes to discuss them here. DBAs commonly establish aliases and functions by setting them in the $HOME/.bashrc file. For example, here we created a file named dba_fncs and placed the following lines of code in it:

#------------------------------------------
# cd to alert log directory
function ad {
 if [ $ORACLE_SID = "O1212" ]; then
    cd  /u01/app/oracle/diag/rdbms/o1212/O1212/trace
 elif [ $ORACLE_SID = "DWREP" ]; then
    cd /orahome/app/oracle/diag/rdbms/dwrep/DWREP/trace
 fi
 pwd
} # ad
#------------------------------------------

A common practice is to create a bin directory beneath the oracle account’s home directory and place the dba_fncs file in HOME/bin. The dba_fncs file can be manually sourced as follows:

. $HOME/bin/dba_fcns

If you put the prior line of code in the $HOME/.bashrc file, the functions in the dba_fncs file are sourced and available for you to use as command shortcuts every time you log on.

If you ever wonder whether a shortcut is an alias or a function, use the type command to verify a command’s origin:

$ type ad
ad is a function
ad ()
{
  if [ $ORACLE_SID = "O1212" ]; then
     cd /u01/app/oracle/diag/rdbms/o1212/O1212/trace;
    else
      if [ $ORACLE_SID = "DWREP" ]; then
            cd /orahome/app/oracle/diag/rdbms/dwrep/DWREP/trace;
      fi;
  fi;
  pwd
}

2-8. Providing Input to Commands

Problem

You want a shell command to receive its input from a file or another process instead of commands typed from the keyboard.

Solution

In Linux/Solaris, you can instruct a command to receive its input from a file with the < character. This technique is known as redirection. In this example, the mailx command is used to send a trace file named to an e-mail address:

$ mailx -s "trace file" [email protected] <O1212_ora_21018.trc

You can also use the output of one command as the input to another command. This technique is known as pipelining. The pipe (|) character instructs a process to receive its input from the output of another process. This example uses the output of the cat command as the input to the mail command:

$ cat O1212_ora_21018.trc | mailx -s "trace file" [email protected]

This technique of piping the output from one command to another is an extremely powerful tool. It is called a pipe because the output of the first command flows through the pipe and becomes the input of the next command. You can also think of the pipe as a temporary memory buffer that holds the output from the command to the left of the pipe. The command to the right of the pipe uses the output stored in the memory buffer as its input. DBAs and developers use this method to chain commands together to perform complex tasks. Many examples of this approach are provided throughout the book.

How It Works

In Linux/Solaris, there are three data streams associated with a process:

  • Standard input (also called standard in or stdin)
  • Standard output (also called standard out or stdout)
  • Standard error (also called stderr)

Figure 2-1 displays the three data streams associated with each process. Starting on the left side of the figure, standard input is the data provided to the process, which is usually data entered by you from the keyboard. As demonstrated in the “Solution” section of this recipe, standard input can also come from a file or as the output of another process.

9781484212554_Fig02-01.jpg

Figure 2-1. Process input and output data streams

Shell programs often generate output data. By default, standard output data is directed to the terminal. Standard output can also be redirected to a file or another process.

Sometimes shell programs generate error messages. By default, standard error messages are displayed to your terminal. Like standard output, standard error messages can be redirected to a file or another process.

The process doesn’t care where its input comes from or where the output is delivered. This means you can string together combinations of commands that feed output from one command to be used as the input to another command. This piping of command output to another command’s input is a very powerful and flexible feature of the shell.

Table 2-4 summarizes the ways in which standard input, output, and errors can be redirected using the Bash shell.

Table 2-4. Command Input and Output Redirection Operators

Operation

Bash Shell Redirection Syntax

Reads standard input from a file

command <file

Reads standard input until end of marker

command <<end of marker

Writes standard output to a file

command >file

Appends standard output to end of file

command >>file

Writes standard output and standard error to separate files

command >file 2>file2

Writes standard output and standard error to the same file

command >file 2>&1

Writes standard output and standard error to the same file

command &> file

Appends standard output and standard error to the end of a file

command >>file 2>&1

Sends (pipe) standard output of first command to input of second command

command | command2

Sends (pipe) standard output and standard error to input of second command

command 2>&1 | command2

Some additional explanation is required for interpreting the second column of Table 2-4. Notice that the < and << redirection operators are used to redirect standard input. The > and >> redirection operators are used to redirect standard output. Also notice that the redirection operators > and >> are shorthand for 1> and 1>>.

The 2> and 2>> redirection operators are used to redirect standard error. The syntax 2>&1 instructs the shell to redirect the standard error stream to the same location as standard output. In the Bash shell, you can also use the syntax &> to send both standard error and standard output to the same file.

The &0, &1, and &2 file descriptors are synonymous with the /dev/stdin, /dev/stdout, and /dev/stderr files, respectively. To illustrate this point, this example uses the file /dev/stdout to redirect standard error to the same location as standard output:

$ cat initBRDSTN.ora 1>myfile.txt 2>/dev/stdout

The previous command is equivalent to the following:

$ cat initBRDSTN.ora 1>myfile.txt 2>&1

The previous command directs the standard output 1> to be sent to myfile.txt. If any errors are encountered when issuing the command (for example, if file initBRDSTN.ora doesn’t exist), the standard error stream 2> is sent to the same location as standard out (which is myfile.txt).

2-9. Redirecting Command Output

Problem

You want to save the output of a command to a file.

Solution

By default, the output from a command displays on your terminal. The > character redirects the output of a command to a specified file. The > character is synonymous with 1>. For example, the following command takes the output of the cat command and places it in a file named output.txt:

$ cat init.ora >output.txt

If the init.ora file doesn’t exist, you’ll receive an error message such as this:

cat: init.ora: No such file or directory

How It Works

You should know about some other interesting features of redirecting command output. For example, you can also instruct the shell command to redirect any errors that are encountered when running a script to a separate file. The 2> characters specify where errors should be written. Just as > means redirect output to a file, 2> means redirect error messages to a file. This example redirects standard output to the file output.txt and sends any error messages encountered to errors.txt:

$ cat init.ora >output.txt 2>errors.txt

You can also use a shorthand notation to send both standard output and error messages to the same file:

$ cat init.ora >output.txt 2>&1

The 2>&1 notation instructs the shell to send output stream number 2 (error output) to the same place as output stream number 1 (standard output). You’ll find it useful to use this notation when running scripts such as database-monitoring jobs.

If for any reason you don’t want to overwrite the output file, use the >> syntax, which instructs the shell to append any messages to the end of an existing file:

$ cat init.ora >>output.txt 2>&1

2-10. Sending Output to Nowhere

Problem

You want to run a command, but you don’t want the output to be shown or saved anywhere.

Solution

If you don’t want text to appear on your screen or saved in a physical file, you can send it to the proverbial “bit bucket” (referred to as the /dev/null device).

The /dev/null device is useful when you don’t want to see all the error messages generated by a command. For example, the following find command generates error messages for directories that it can’t read:

$ cd /
$ find . -name "alert*.log"

Here is a partial snippet of the output:

find: cannot read dir ./var/fm/fmd/xprt: Permission denied
find: cannot read dir ./var/fm/fmd/rsrc: Permission denied
find: cannot read dir ./var/fm/fmd/ckpt: Permission denied

To eliminate those error messages, send the error output to the /dev/null device:

$ find . -name "alert*.log" 2>/dev/null

If you know you will run a program or command that generates output you don’t need, you can redirect the output to the /dev/null device.

Image Tip  The /dev/null device can also be used to quickly reduce a large file to 0 bytes without deleting the original file (see recipe 5-31 for details).

How It Works

The /dev/null file is a special file known as the null device. It also called slash dev slash null or the bit bucket. It contains nothing, and any output you send to this special file will never be seen again.

The following is a slightly different example of how to use the /dev/null device. Suppose that you want to test how long it takes to read a file, but you don’t want the output of the dd command to actually create a file. In this example, the output is sent to the /dev/null device using the of parameter:

$ time dd if=/u01/dbfile/O1212/users01.dbf of=/dev/null

Here is some sample output:

20496+0 records in
20496+0 records out
10493952 bytes (10 MB) copied, 0.0820684 seconds, 128 MB/s
real    0m0.09s
user    0m0.00s
sys     0m0.01s

The previous command is useful for troubleshooting disk I/O issues without the overhead of physically creating a file. If you divide the data file size by the total time the command took to run, you get the disk I/O rate. You can compare that value with V$BACKUP_ASYNC_ IO.EFFECTIVE_BYTES_PER_SECOND to help you determine whether the Recovery Manager (RMAN) has a potential I/O problem.

CHECKING FOR DATA FILE CORRUPTION

In the old days, before there were tools such as dbverify and Oracle Recovery Manager (RMAN), DBAs needed a method to detect corrupt blocks in data files. To accomplish this, DBAs used the export utility. As the export utility runs, it writes information on detected corrupt blocks to the database alert.log file.

If the DBA wanted to check only for block corruption without saving the output of the export to a file, the output could be sent to the /dev/null file, as shown here:

$ exp user/pass full=y file=/dev/null

Thus, the DBA could detect database corruption without actually having to create a potentially large export file. Having said that, you should not rely on this approach for detecting database corruption because it has several known limitations (for example, it can’t detect corruption in blocks above a table’s high water mark—see MOS note 214369.1 for details). You should instead use dbverify or RMAN to detect bad blocks in Oracle database data files.

2-11. Displaying and Capturing Command Output

Problem

You want to see the output of a command onscreen and store that output in a file.

Solution

If you want to capture only the output associated with the execution of a specific OS command, you can use the tee command, which enables any output generated by a command to be written to both the screen and a designated file.

The following example runs the ls command to list all files in a directory. It also saves that output to a file that can later be viewed to determine the names and sizes of files on a particular date:

$ ls -altr /ora01/BRDSTN | tee /home/oracle/log/oct15_df.log

Here is some sample output of what is displayed to the screen and recorded in the log file:

-rw-r----- 1 oracle oinstall 52429312 Oct 15 08:00 redo03a.log
-rw-r----- 1 oracle oinstall 838868992 Oct 15 08:25 undotbs01.dbf
-rw-r----- 1 oracle oinstall 524296192 Oct 15 08:30 system01.dbf
-rw-r----- 1 oracle oinstall 15056896 Oct 15 08:37 control01.ctl

How It Works

The tee command is useful when you want to interactively see the output of a command displayed onscreen and also require that the display be logged to a file that can be inspected later for debugging or troubleshooting activities. For example, when you back up a database and you want to log all output to a file, you can do so with the RMAN utility as follows:

$ rman target / | tee rman.log

Any output from commands you run while connected to RMAN are displayed onscreen and captured in the log file.

Image Tip  The tee command is similar to a plumbing t-splitter pipe in that it allows one input stream to be split into separate output pipes.

2-12. Recording All Shell Command Output

Problem

You’re performing a database upgrade and you need to run several SQL scripts. You want to record the output of everything printed to your screen to a log file.

Solution

The script command enables the recording of all output printed to your screen to also be written to an OS file. This example writes all output to a file named upgrade.log:

$ script upgrade.log
Script started, file is upgrade.log

From this point on, all output printed to your terminal is also recorded in the script upgrade.log. To end the script logging session, press Ctrl+D or type exit. You should see a message similar to this:

Script done, file is upgrade.log

How It Works

The script command is invaluable when you need to capture all output being printed to the terminal. This command stores all output in an OS file that can later be used to verify the tasks performed and whether the operations succeeded or failed.

If you don’t specify a file name when using script, a default file with the name of typescript is created. If you need to append to an already existing file, use script with the -a option, as shown here:

$ script -a upgrade.log

This code enables the capture of all output from all scripts that are being run. It can be extremely useful when you have a mix of OS commands and database commands and want to capture the output of every operation.

DBAs use the script command when the person who developed upgrade scripts (DBA #1) is passing the scripts to a different team member (DBA #2) to have those scripts executed in another database environment. In this scenario, DBA #2 will start a script job, run the upgrade scripts, end the script logging, and send the generated log file to DBA #1 for verification purposes.

2-13. Changing the Login Shell

Problem

Your system administrator has set your OS account to use the Korn shell, and you want to change it to the Bash shell.

Solution

Use the chsh (change shell) command to change the default login shell. You can specify the desired login shell directly with the -s option. In this example, the default shell for the oracle user is changed to the Bash shell:

$ chsh -s /bin/bash
Changing shell for oracle.
Password:

After successfully entering the password, a message “shell changed” is displayed. Now when you subsequently log on to the oracle account, the default shell will be the Bash shell.

How It Works

You might want to change your shell if the default is something other than your preferred shell. We recommend that you use the Bash shell on Linux/Solaris systems. The Bash shell is very robust and incorporates most of the useful features from the Bourne shell, Korn shell, and C shell.

The valid shells available on your server are stored in the /etc/shells file. You can use the chsh -l command or the cat command to view the contents of the /etc/shells file. This example uses the cat command to display the available shells:

$ cat /etc/shells
/bin/sh
/bin/bash
/bin/tcsh
/bin/csh
/bin/ksh

Table 2-5 describes the various shells available in Linux/Solaris environments.

Table 2-5. Descriptions of Popular Shells Available

Shell

Description

bsh or sh

The original Bourne shell written by Steve Bourne.

bash

The Bourne Again shell is considered to be one of the most robust shells.

ash

The Almquist shell has a smaller footprint than the Bash shell and is useful on systems in which disk space is limited.

ksh

The Korn shell is popular among DBAs on many varieties of UNIX.

pdksh

This shell is a public domain implementation of the Korn shell.

tcsh

The TENEX C shell is an enhanced version of the C shell.

csh

The C shell is like the C programming language and is popular on many older variants of UNIX.

You can verify what your default login shell has been set to by viewing the contents of the /etc/passwd file. For example, to view the default shell for the oracle user, use the cat and grep commands:

$ cat /etc/passwd | grep -i oracle
oracle:x:2000:500:sb-db1 Oracle Account:/orahome/oracle:/bin/bash

Image Note  You do not need any special privileges or the assistance of your system administrator to use the chsh command.

2-14. Modifying Command Path Search

Problem

You need your shell to automatically find executable programs that aren’t currently in a directory included in your PATH variable. You want to add directories to your PATH variable.

Solution

You can manually add a directory to your PATH variable by using the export command. The following example prepends the /orahome/app/oracle directory to the current contents of the PATH variable:

$ export PATH=/orahome/app/oracle:$PATH

In the previous line of code, the PATH variable is defined to be the directory containing the Oracle binaries plus the contents of PATH directory. You separate directories in the PATH variable with a colon (:).

If you want to have a directory added to your PATH variable every time you log on to your database server, place the export command in a special startup file (see recipe 2-5 for details).

How It Works

The export command allows you to define variables that will be available to subsequently executed commands. You can add directories to the PATH variable by exporting it. To verify the contents of your PATH variable, you can use the echo command:

$ echo $PATH

Occasionally, you might encounter an Oracle RMAN issue when the directory /usr/X11R6/bin appears in the PATH variable before the ORACLE_HOME/bin directory. You see an error message when you try to start rman:

$ rman target /
rman: can’t open target

You received this error because there is an rman executable in the /usr/X11R6/bin directory that has nothing to do with the Oracle rman backup and recovery utility. In this scenario, you have to modify your PATH variable to ensure that ORACLE_HOME/bin comes before /usr/X11R6/bin:

$ export PATH=$ORACLE_HOME/bin:$PATH

The other alternative is to rename the rman executable in /usr/X11R6/bin to something like rman.X11.

Image Tip  See MOS note 101050.1 for issues regarding the PATH variable and the rman executable.

CURRENT WORKING DIRECTORY AND PATH

To set your path to include the current working directory, simply use this:

$ export PATH=$PATH:.

Security experts recommend against having the current working directory referenced near the beginning of a PATH variable because a malicious person could place a program in a directory that does bad things to your system. For example, somebody could place a script named ls in a user’s home directory and have commands within the ls script delete files recursively. If the bad ls script is referenced before the ls command in /bin or /usr/bin, the results could be ugly.

2-15. Viewing Built-in Commands

Problem

You wonder whether you’re running a built-in version of a shell command or using the binary program located in the /bin directory.

Solution

Use the help command to view all built-in commands. For example, if you type help with no arguments, all built-in commands display:

$ help

Here is a partial listing of the output:

alias [-p] [name[=value] ... ]     bg [job_spec ...]
 bind [-lpvsPVS] [-m keymap] [-f fi break [n]
 builtin [shell-builtin [arg ...]]  caller [EXPR]
 case WORD in [PATTERN [| PATTERN]. cd [-L|-P] [dir]
 command [-pVv] command [arg ...]   compgen [-abcdefgjksuv] [-o option
 complete [-abcdefgjksuv] [-pr] [-o continue [n]

You can also use the type command to determine whether a program is built in. Use the -a option of type to print all locations in the PATH variable that include a command (including all aliases and functions). The following example shows that there is a built-in pwd command and also a pwd program in the /bin directory:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

Image Note  You might wonder why Linux/Solaris provides both a built-in command and a program for pwd. Because some shells might not have a built-in command for pwd, a program is explicitly provided in the /bin or /usr/bin directory.

How It Works

Some commands are built in to the Bash shell. Built in simply means that the shell contains its own version of the command. Therefore, if you run a built-in command such as pwd, the Bash shell runs its version of the pwd command instead of the executable program located in the /bin or /usr/bin directory. If you want to explicitly run the pwd command in the /bin directory, specify the complete path and file name. This example shows how to run the pwd program located in the /bin directory:

$ /bin/pwd

In some situations, it’s important to know whether a command is built in to the shell. Built-in commands execute faster than their counterparts in the /bin or /usr/bin directory because there is no overhead of looking in directories for the command and then loading the command into memory for execution.

Additionally, there are code portability issues to consider. Built-in commands typically have the same behavior from one OS to another, whereas the commands in the /bin and /usr/bin directories might behave differently between different ports of Linux/Solaris (especially older versions).

Built-in commands don’t start a separate process (sometimes called forked, child, or spawned) when they are executed. This is a requirement of some commands such as cd because a child process can’t modify its parent process. If cd were executed as a child process, it couldn’t modify the current working directory of the parent process and therefore wouldn’t be of much use. For this reason, the Bash shell contains its own executable code for the cd command. Table 2-6 describes some of the more commonly used Bash built-in commands.

Table 2-6. Commonly Used Bash Built-in Commands

Bash Built-in Command

Description

cd

Changes directories

echo

Displays strings and the contents of variables

help

Displays help on Bash built-in commands

history

Shows recently run commands

pwd

Prints the current working directory

ulimit

Sets and displays various system resource limits imposed on the shell

You can instruct the Bash shell to explicitly run a built-in command with the builtin command, which can be useful when porting scripts between different versions of Linux/Solaris.

The builtin command runs the built-in version of the command, even if there is an alias declared for it. This example runs the pwd built-in command:

$ builtin pwd

Likewise, you can explicitly instruct Bash to run the Linux/Solaris program version of a command, even if there is a built-in command or alias defined with the same name. This example runs the program version of the pwd command located in the /bin directory:

$ command pwd

You can also use the enable command to enable or disable the use of a built-in command. This example uses enable -n to disable the pwd built-in command:

$ enable -n pwd
$ type pwd
pwd is /bin/pwd

This example re-enables the pwd command:

$ enable pwd
$ type pwd
pwd is a shell builtin

Image Tip  You can also use the man bash command to view all built-in commands. When viewing the man page, search for “shell builtin” string.

2-16. Setting the Backspace Key

Problem

You entered a command incorrectly and you want to backspace over previously entered characters so that you can correct them. When you attempt to use the Backspace key, it shows the ^? characters instead of deleting the previously entered characters.

Solution

Use the stty command to set your Backspace key to delete characters properly. The following bit of code sets the Backspace key to delete characters:

$ stty erase Ctrl+Backspace

In the previous command, ensure that you press the Ctrl and Backspace keys at the same time. This might vary depending on your system; for example, the following is an alternative way of setting the Backspace key:

$ stty erase <Backspace>

In the previous line of code, don’t type the word Backspace; instead, press the Backspace key.

How It Works

The stty command is used to view and change terminal settings. To view current stty settings, issue the following command:

$ stty -a
speed 38400 baud; rows 36; columns 97; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
...

When you work with older versions of Linux or Solaris, you might be logged on to a server when the Backspace key doesn’t work. In such situations, you have to manually set the Backspace key to function correctly. If you want the Backspace key to be automatically set every time you log on to the server, place the stty command in a special startup file (see recipe 2-5 for details).

Image Note  On some older Linux or Solaris systems, you might need to use the stty erase ^H command or the stty erase ^? command to set the Backspace key.

2-17. Typing a Long Command in Multiple Lines

Problem

You want to type a long command, but it doesn’t fit nicely on one line.

Solution

To extend a line of code to the next line, use the backslash () character, followed by pressing Enter or Return. The following example shows how to break a long rman connection command over several lines:

$ /usr/oracle/product/10.2.0/db_1/bin/rman 
>  target / 
>  catalog rman/rman@db11g_bllnx1
>  cmdfile=/home/oracle/scripts/rmancheck.rmn
>  msglog=/home/oracle/rmanlog/rmancheck01.log append

Although you could have typed the previous command on one line, consider breaking a command up into multiple lines when you have a limited terminal width.

How It Works

Sometimes it is desirable to extend a command across multiple lines for readability reasons. When you type followed by pressing Enter or Return, the next line will be preceded by the > character. This character indicates that the command has been extended to the next line. Both the backslash and the new line marker are ignored when this technique is used.

It doesn’t matter which location within the command the backslash is placed; you can break a command over as many lines as necessary.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset