Technophile, Contemplative, Raging Geek

Embracing the UNIX Terminal (Part 6)

Join my mailing list to receive the latest news and announcements!

UNIX Quote

Today, we’re going to discuss two topics that will either clarify fundamental aspects of the command prompt, or help you personalize the terminal environment into something you feel more comfortable with.

Directing Input and Output

Standard Input and Standard Output

The standard input (stdin) is the keyboard. It is the main way that we get information into UNIX. Typically, the standard output (stdout) is the terminal, i.e., the window or screen that you’re seeing via the Terminal application. There are special UNIX files that represent the stdin and stdout, and they exist inside the /dev folder.

/dev/stdin

/dev/stdout

Directing Output to a File

Instead of having our commands’ output sent to the stdout (i.e., the terminal), we can re-direct it towards a file. Furthermore, the file doesn’t have to exist at the time of command execution. We can create it on-the-fly.

For example, we can re-direct the contents of a directory to a text file.

ls -lah > directoryContents.txt

In addition, we can use redirection to concatenate two different files.

cat file1.txt file2.txt > file3.txt

Keep in mind, using redirection in this manner is destructive, i.e., it will overwrite files that already exist.

Appending to a File

If you wish to append to an existing file using redirection, you can use the >> syntax.

echo "Do not forget the milk." >> todo.txt

Directing Input from a File

Also, we can utilize redirection when moving in the opposite direction, i.e., instead of sending a command input from the keyboard, we can send it from a file.

Here, I am sending the wc command the text from a file that I’d like a word count on.

wc < post.txt

In this example, post.txt serves as the input for wc. If I used the command as I’ve previously shown (i.e., wc post.txt), the file would have been passed into wc as an argument, instead.

We can combine input and output redirection to create some interesting workflows.

sort < names.txt > sortedNames.txt

Arguments for input/output redirection always have to be files or directories.

Piping Output to Input

Pipes extend the redirection idea, except instead of dealing with files and directories, pipes can be used to take output from a command and use it as input for another command.

echo "What's up?" | wc

cat names.txt | sort | uniq > uniqueSortedNames.txt

The pipe can be used to give us paginated control of handy outputs, as well.

ps aux | less

Super sweet!

Suppressing Output

If you wish to suppress output from a command, you can redirect it to the null device (/dev/null), which is similar to the previously mentioned /dev/stdin and /dev/stdout files.

cat superSecretStuff.txt > /dev/null

dev null

UNIX will discard any information sent to the null device. Think of it as a void from which no digital detritus returns.

Configuring your Working Environment

Profile, Login, and Resource Files

Logging into bash on a Mac is equivalent to opening a Terminal window. Upon logging into a bash shell, several important things occur. The master, default commands that every bash user gets is loaded from /etc/profile. Also, UNIX looks for one, and only one, of these locations, in the following order:

  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile
  • ~/.login

Once it finds one of these, it ignores the rest.

When you first open a Terminal window, you are in a login shell. Entering in bash will open up a sub-shell. Once inside the sub-shell, the commands in the ~/.bashrc file are executed. Whatever content is inside of the ~/.bash_profile file is not available in the sub-shell, and whatever is in the ~/.bashrc file is not available to the login shell.

When you log out of the bash shell, the contents of ~/.bash_logout are executed.

Bash Shells: Login vs. Non-Login

Before we start configuring our shell environment, we want to ensure that all of our customizations are available to both login and non-login shells. This can be accomplished by placing the following code into your ~/.bash_profile file.

if [ -f ~/.bashrc]; then
     source ~/.bashrc
fi

Now, place all of your configurations in ~/.bashrc.

Setting Command Aliases

Once you get the hang of writing common UNIX commands, you may wish you didn’t have to write out the same convoluted syntax, over and over again, or, perhaps, there is a particularly long command you need to frequently implement, but are loath to, for fear of typos.

UNIX addresses these issues with command aliases, i.e., shortcuts for command execution.

To see currently defined aliases, enter the alias command.

For example, I defined an alias to quickly examine the latest entries for my Mac’s system log:

alias sl='tail -f /var/log/system.log'

To remove an alias, use the unalias command and the alias name.

unalias sl

Remember, unless you define your alias in the ~/.bashrc file, it will only last for your current bash session.

Setting and Exporting Environment Variables

An environment variable is equivalent to a shell variable, and the dollar sign ($) is used to tell UNIX that we want to return the value of a variable.

echo $SHELL

When you set a variable, you don’t use the dollar sign. It’s only used when you retrieve its contents.

MYNAME='Paul Ciano'

echo $MYNAME

Just like with aliases, your created variables only exist within your session, unless you save them to either ~/.bash_profile or ~/.bashrc. Furthermore, declared variables will not be available to child processes that bash starts on your behalf. By default, these variables are only available to bash itself.

To have bash pass along these variables to other commands, programs, and scripts, you need to export them, as well. So, when creating variables, make sure you add the requisite lines to either ~/.bash_profile or ~/.bashrc, as follows.

MYNAME='Paul Ciano'

export MYNAME

Variables can be used to set configuration options for a UNIX environment and the programs that it uses.

export LESS='-M'

Setting the PATH Variable

The PATH variable is a colon delimited list of file paths that UNIX uses when it’s trying to locate a command that you want to run.

PATH

echo $PATH

It is common to amend this variable with additional paths.

export PATH="/local/bin:$PATH"

Here, we are adding the location /local/bin to the current value of the PATH variable. Note that double quotes are necessary when using $, otherwise UNIX thinks we are referring to a literal string.

Configuring History with Variables

There are five different variables that we can configure in regard to command history.

  1. HISTSIZE
    • Set the maximum number of entries to be stored in the .bash_history file.
  2. HISTFILESIZE
    • Sets the maximum size of the .bash_history file.
    • export HISTFILESIZE=1000000
  3. HISTTIMEFORMAT
    • Can be used to specify the strftime format
    • export HISTTIMEFORMAT='%b %d %I:%M %p '
  4. HISTCONTROL
    • Used to control how bash stores your command history. The following entry will tell UNIX to ignore duplicates and to ignore commands with a leading whitespace.
    • export HISTCONTROL=ignoreboth
  5. HISTIGNORE
    • Create a colon delimited list of commands to ignore.
    • export HISTIGNORE="history:pwd:exit:df:ls:ls -lah"

Tasty Tip: Using a leading whitespace to have command history ignore a command can be useful when you’d like to prevent the saving of passwords (e.g., when you use the sudo command).

Customizing the Command Prompt

You can customize your command prompt through a shell variable, PS1.

The following command prompt formatting codes are available:

Command Prompt Formatting Codes
Code Command Prompt Output
\u username
\S current shell
\w current working directory
\W basename of current working directory
\d date in “weekday month date”
\D{format} date in strftime format
\A time in 24-hour HH-MM format
\t time in 24-hour HH-MM-SS format
\@ time in 12-hour HH-MM
\T time in 12-hour HH-MM-SS format
\H hostname
\h hostname up to first period
\! history number of this command
\$ when UID is 0(root), a “#”, or otherwise a “$”
\\ a literal backslash

Logout File

Finally, if there are any commands you’d like executed when logging out of bash, place them in ~/.bash_logout.

Coming Up

Next Time

Next time, you will get a better appreciation of the full capabilities of the UNIX terminal as we dive into UNIX power tools. Stay tuned.

Need more information? Try a search or a related post.

5 Responses to “Embracing the UNIX Terminal (Part 6)”

Leave a Reply

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS