Environment Variables in Unix

Each process in Unix has its own set of environment variables. They’re called environment variables because the default set of such variables consists mostly of session-wide variables used for configuration purposes.

From the point of a Unix shell though, environment variables can be accessed the same way as any other variable.

Common environment variables in Unix

Most well known environment variables are the following:

  • USER – username of a Unix user
  • HOME – full path to a user’s home directory
  • TERM – terminal or terminal emulator used by a current user
  • PATH – list of directories searched for executable files when you type a command in Unix shell
  • PWD – current directory

Example of using environment variables

Using Unix username to control the flow of a script

Sometimes it’s quite useful to double-check the username of whoever called your script – maybe you’ll want to provide different functionality for different users. A common use of such scenario is many commands which are not meant to be run by anyone except superuser (root). If you try running them as a normal user, you’ll be told right away that you have to be root in order to use them.

In Unix scripts, the opposite functionality is more useful: making sure you don’t run a script as root. Here’s one way of doing it:

#!/bin/bash
#
echo "- Verifying the current user..."
if [ "$USER" = "root" ]; then
        echo "You are ROOT, please run as a normal user";
        exit
else
        echo "User $USER, script is ready to continue"
fi
        echo "Work in progress..."

And that’s how it would work:

ubuntu$ /tmp/script.sh
- Verifying the current user...
User greys, script is ready to continue
Work in progress...

If I use sudo in Ubuntu to run the script as root, I’ll get a warning and the script will end:

$ sudo /tmp/script.sh
- Verifying the current user...
You are ROOT, please run as a normal user

Getting full list of environment variables

In case you feel like exploring, you can use the env command to get a full list of currently set environment variables (the output in this example is abridged):

ubuntu$ env
TERM=xterm
SHELL=/bin/bash
USER=greys
MAIL=/var/mail/greys
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games
PWD=/home/greys
EDITOR=vim
..

That’s all I wanted to share with you today. Let me know how exactly you’d like me to further expand and cover this topic – more posts will definitely follow!
h3>Recommended books:

See also:




Unix scripts: basic arithmetic operations

As I was writing the Time and date in Unix scripts post last week, I’ve realized that there’s one really useful feature of Unix shell scripting which I haven’t covered on my pages here: it’s the double bracket parenthesis which allows you to evaluate arithmetic expressions.

Basic arithmetic calculations in Unix scripts

In most scenarios, your script will need only basic arithmetic operations: summing or subtracting numbers, multiplying or dividing them. Using only these operations, you’ll be able to implement all sorts of counters and calculate percentages or any other progress indicators you may need.

So far, I’ve only shown you this way of evaluating arithmetic expressions in Unix shell (yes, it’s not a script – you can just type commands one after another right in your shell prompt):

ubuntu$ START=1
ubuntu$ FINISH=5
ubuntu$ ELAPSED=`expr $FINISH - $START`
ubuntu$ echo $ELAPSED
4

But an even better way to evaluate arithmetic expressions is to use the built-in functionality of double brackets. Just continue typing in your shell:

ubuntu$ ELAPSED2=$(($FINISH - $START))
ubuntu$ echo $ELAPSED2
4

You see, everything that is inside double brackets gets evaluated and then this calculated value is assigned to the variable. I’m using a different variable – ELAPSED2 – to clearly show that this calculation has nothing to do with the original ELAPSED variable.

Assignment operator

If you wonder about the theory behind such a way of evaluating expressions, I should talk a bit about using variables in Unix shells.

As you probably remember, when you’re assigning your variable a new value, you’re simply specifying the name of the variable to the left of the expression, then use the = sign (it’s not just a symbol but an assignment operator by the way), and to the right of this operator goes the expression which represents the new value:

ubuntu$ MYVAR=123

Variable substitution operator

As you also remember, when you want to access the value of the variable, for example to print it out, you use the variable name with a leading $ sign. That’s because $, once again, isn’t just a fancy symbol, but in fact a special character in Bash – it’s a variable substitution operator, which means your Unix script substitutes the variable name you’re specifying in the script with the value of the variable:

ubuntu$ echo $MYVAR
3

Using the substitution operator ($) before the name of a variable is crucial. If you omit the $ sign, your shell will think you have simply passed it a text string, and will not recognize it to be a name of the variable:

ubuntu$ echo MYVAR
MYVAR

Expression evaluation explained

Coming back to arithmetic evaluations, you can probably see now that a line similar to this:

ubuntu$ ELAPSED=$(($FINISH - $START))

uses the variable substitution operator ($) and it’s therefore only logical that the further specified expression gets evaluated and the ELAPSED variable gets assigned with the resulting value.

Once again, using $ sign is crucial as without it your shell will not understand you:

ubuntu$ ELAPSED=(($FINISH - $START))
sh: syntax error near unexpected token `('

So, what do you think? I hope this makes sense to you, and will be sure to use this technique from now on – once you get used to it, it’s really easy to write and read shell scripts based on this functionality.

Let me know if there’s anything else you’d like to hear an explanation of! I’ll do my best! 🙂

See also:




Unix Scripting: Time and Date

If you have followed this blog for a while, you should remember how to use variables in Unix shell scripts.

Going further, I’d like to show you some basics of working with time and date in your scripts – generating all sorts of timestamps and timing some parts of your script for reporting purposes.

The history of (Unix) time

In case you didn’t know, time in Unix starts with a Unix epoch, sometimes also referred to as POSIX epoch. The Unix epoch is the time 00:00:00 UTC on January 1, 1970.

Most of Unix-like system today store and calculate this time according to Unix epoch, which means they all have an internal counter which counts the number of seconds elapsed since midnight of January 1, 1970.

As you can imagine, this is a pretty big number (it passed 1,000,000,000 seconds back in 2001, just so that you know), and reporting in directly would not be very useful to real humans. Because of this, most of Unix time and date reporting commands and functions do the conversion from Unix time into something more meaningful to the end user.

While for the vast majority of time and date related tasks this conversion is good, a task of timing certain events can sometimes benefit from using raw second counters and simply subtracting them when needed.

Getting Unix time and date

In Unix shells, the easiest way to get a current time and date is to use the date command:

ubuntu$ date
Tue Jun 10 10:46:07 IST 2008

date is a very smart command, and apart from this default behavior it supports template system for printing the current time and date – so you can use it to report only specific part of the time and date like the current hour or the day of a week or the year.

Read the man page for date (type man date in your shell prompt) to learn all the details, but this is how you use date output templates:

ubuntu$ date "+%b %d, %Y"
Jun 10, 2008

In this example, the %b parameter in this template represents the short name of the current month, %d is the day of the month, and %Y is the four-digit representation of the current year.

Timing parts of your Unix script

If you’re after timing some parts of your script, you’ll need to use two variables: one for saving the time before the start of an observed part of the script, and another one for saving the time after the same piece of code.

These two variables will be used to subtract the time and report the elapsed time in seconds, so in order to do this we’ll need the date command to report time in seconds. That’s why I’ve given you an introduction to Unix time earlier: date reports the number of seconds since the Unix epoch:

ubuntu$ date +%s
1213091896

If you run it just a few seconds later, you’ll see a different number:

ubuntu$ date +%s
1213091922

That’s why, if such values are saved and then subtracted, we’ll get the elapsed time in seconds.

Here’s a simple script showing how this is done:

#!/bin/bash
#
START=`date +%s`
echo "Script start time (Unix epoch): $START"
#
echo "- sleeping for 3 seconds..."
sleep 3
echo "- sleeping for 2 seconds more..."
sleep 2
#
FINISH=`date +%s`
echo "Script finish time (Unix epoch): $FINISH"
#
ELAPSED=`expr $FINISH - $START`
echo "Elapsed time: $ELAPSED"

And if you run it, you will see this output:

ubuntu$ /tmp/time-example.sh
Script start time (Unix epoch): 1213092131
- sleeping for 3 seconds...
- sleeping for 2 seconds more...
Script finish time (Unix epoch): 1213092131
Elapsed time: 5

That’s all I wanted to show you today. In future posts, I’ll show you a few more things you can do regarding timing and timestamps in Unix. Until then – good luck with your scripting, and feel free to ask if you need any more help!

See Also