How To Use This Website

For all the new visitors of this blog, I’ve just created a Using Unix Tutorial page which is linked from the sidebar.

Please feel free to have a look and let me know if there’s any more introductory information I can add to make it even easier for you to find and get exactly what you came looking.




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 Tutorial Digest: Interesting Links #1

Every week there’s a few announcements or articles which I find particularly interesting, and so I’ve decided to share them with you. I’m not a Unix guru (yet), but if any of the listed materials require further explanation – do feel free to ask and I’ll be glad to help.

Ubuntu 8.04.1 release

About a week ago, the first update to Ubuntu 8.04 was announced – Ubuntu 8.04.1 TLS. I have completed my experiment of using Ubuntu Hardy as my desktop OS a few weeks ago, and so haven’t upgraded yet – but I think this release is not so useful for anyone who’s been automatically updating their system – it’s just another milestone and a way to download a complete Ubuntu 8.04.1 as one image.

The highlights for me would be Firefox upgraded to the final 3.0 release and Gnome upgrade (it’s 2.22.2 in this release).

Gentoo Linux 2008.0 release

For some of you, it’s probably been a long-awaited release. Move to 2.6.24 kernel provided support for much more hardware, and this is bound to look good with the updated and much improved Gentoo installer.

Read more in the official Gentoo Linux 2008.0 announcement.

Cache poisoning vulnerability in DNS

Dan Kaminsky has found quite a nasty weakness in DNS implementations: deficiencies in the DNS protocol and common DNS implementations
facilitate DNS cache poisoning attacks.

Thanks to the seriousness of the problem and a great coordination, most of the vendors were given the time to publish a fix, so the Vulnerability Note VU#800113 contains a comprehensive list of vulnerable implementations of DNS (both server and client sides are affected, by the way!) and links to fixes provided by various vendors.

Whether you’re managing a server farm or just a Linux desktop – be sure to update!

Wine 1.1.1 release

Things are going much faster with Wine development after the 1.0 release – it didn’t take long for the 1.1 to appear, and now almost every other week brings another great update with tons of bugs fixed.

Wine 1.1.1 release includes more than 50 bugfixes and hundreds of changes since Wine 1.1.0, notably the fixes for Adobe Photoshop CS3 and Microsoft Office 2007 installers, as well as improved video playback and many other improvements.




Ubuntu 8.04 (Hardy Heron) released!

Ubuntu 8.04 TLS

For all of you who were waiting for the next release of Ubuntu, it’s finally here! I’ve been using the beta of Ubuntu 8.04 (Hardy Heron) for the past month or so, and found it an excellent release to work with.

Ubuntu 8.04 links:




How To Find Large Files and Directories in Unix

When you’re trying to clean up your filesystems and reclaim some space, one of the first things you’ll want to do is to confirm the largest directories and individual files you have. This can be easily done using two Unix commands: find command and du command.

Find files larger than a certain size

It’s very simply to find files which are larger than a specified size. The find command accepts a size parameter, and you can specify the limits for file sizes in your command line.

This example finds all the files under /etc directory which are larger than 100k:

root@ubuntu# find /etc -size +100k
/etc/ssh/moduli
/etc/ssl/certs/ca-certificates.cr
/etc/bash_completio

If we look at their sizes, they really are above 100k:

root@ubuntu# ls -l /etc/ssh/moduli /etc/ssl/certs/ca-certificates.crt /etc/bash_completio
-rw-r--r-- 1 root root 215938 Apr 10  2007 /etc/bash_completion
-rw-r--r-- 1 root root 132777 Feb 19  2007 /etc/ssh/moduli
-rw-r--r-- 1 root root 149568 Sep  7  2007 /etc/ssl/certs/ca-certificates.crt

Find files within specified size limits

The real beauty of using find command is that you can specify both the lower and the upper file size limit in one command line. Working off the previous example, we can limit the search to find only files with the size of 100k-150k, quite easily:

root@ubuntu# find /etc -size +100k -size -150k
/etc/ssl/certs/ca-certificates.crt
/etc/bash_completion

As you can see from the syntax, the size specification can contain a sign – plus or minus indicates whether you’re looking for a file with the size above or under a given figure.

Show directory sizes using du

du command takes a little while to run, depending on what directory you pass it as a parameter, but then prints you a list of all the subdirectories along with their sizes. Most common usage is shown below, -s parameter makes the command report a summary of disk usage stats for only the specified directories matching the /usr/* mask (and not their subdirectories), and -k specifies that we want to see the results in kilobytes:

root@ubuntu# du -sk /usr/*
90824   /usr/bin
4       /usr/games
23644   /usr/include
404196  /usr/lib
0       /usr/lib64
116     /usr/local
22020   /usr/sbin
309516  /usr/share
301600  /usr/src

In most Linux systems, this command had been updated to support a -h parameter, which makes sizes even easier to interpret:

root@ubuntu# du -sh /usr/*
89M     /usr/bin
4.0K    /usr/games
24M     /usr/include
395M    /usr/lib
0       /usr/lib64
116K    /usr/local
22M     /usr/sbin
303M    /usr/share
295M    /usr/src

Sorting directory sizes

Now, the previous example would get a lot more useful if you sort the directories by their size. The only problem is that sort -n (numerical sorting) would sort by numbers but ignore the human-readable element (M for megabytes, K for kilobytes, G for gigabytes) thus giving you a complete mess:

root@ubuntu# du -sh /usr/* | sort -n
0       /usr/lib
644.0K    /usr/games
22M     /usr/sbin
24M     /usr/include
89M     /usr/bin
116K    /usr/local
295M    /usr/src
303M    /usr/share
395M    /usr/lib

So what do we to? Luckily for us, Linux implementation of sort supports -h option which does exactly the kind of sorting we needed:

root@ubuntu# du -sh /usr/* | sort -h
0       /usr/lib
644.0K    /usr/games
116K    /usr/local
22M     /usr/sbin
24M     /usr/include
89M     /usr/bin
295M    /usr/src
303M    /usr/share
395M    /usr/lib

See Also




How to Compare Text Files Using diff

If you need to compare two text files in Unix, you’re mostly likely to use the diff command.

Today I’ll talk about the simplest scenario: you want to compare two files and understand if there are any differences.

Suppose you have two files in /tmp directory:
/tmp/1.txt:

aaa bbb ccc ddd eee fff ggg

and /tmp/2.txt:

bbb
c c
ddd
eee
fff
ggg
hhh

I have deliberately created them so short and simple – this way it’s easier to explain how the comparison works. If there are no differences between the files, you will see no output, but if two text files are indeed different, all the text mismatches will be highlighted using the standard diff output:

$ diff /tmp/1.txt /tmp/2.txt
1d0
< aaa
3c2
< ccc
---
> c c
7a7
> hhh

Lines like “1d0 and “3c2 are the coordinates and types of the differences between the two compared files, while lines like “< aaa” and “> hhh” are the differences themselves.

Diff change notation includes 2 numbers and a character between them. Characters tell you what kind of change was discovered:

d – a line was deleted
c – a line was changed
a – a line was added

Number to the left of the character gives you the line number in the original (first) file, and the number to the right of the character tells you the line number in the second file used in comparison.

So, looking at the two text files and the diff output above, you can see what happened:

This means that 1 line was deleted. < aaa suggests that the aaa line is present only in the original file:

1d0
< aaa

And this means that the line number 3 has changed. You can see how this confirms that in the first file the line was “ccc”, and in the second it now is “c c”.

3c2
< ccc
---
> c c

Finally, this confirms that one new line appeared in the second file, it’s “hhh” in the line number 7:

7a7
> hhh

That’s all you need to know to start playing with text comparisons yourself. Stay tuned for more!

Useful command line options for diff

Here are just some of the options, I won’t demonstrate them but simply wanted you to know what’s possible:

-i option – allows you to ignore case when comparing lines (aaa will equal AaA, etc)
-r option – recursively compare directories (and any files found there)
-s option – report identical files (you can script around this if your task is to confirm which files are identical)

Related books

If you want to learn more, here’s a great book:

unix-power-tools
Unix Power Tools




Solaris Devices

This is a very brief introduction into navigating the device paths in Solaris. I’m using a Solaris 10 installed on Sun v490 for all the commands shown below.

Device files in Solaris

Even though all the block and character special device files are traditionally found under /dev directory, if you look closer at your Solaris 10 setup you will notice that they’re not the device files themselves, but instead are just symbolic links to device files under /devices directory.

Solaris uses /devices directory for representing all the physical hierarchy of installed devices and buses found on your hardware system.

The directory tree under /devices copies the actual physical configuration of your hardware, and looks like this:

bash-3.00# ls /devices
iscsi                              pci@8,700000:reg
iscsi:devctl                       pci@9,600000
memory-controller@0,400000         pci@9,600000:devctl
memory-controller@0,400000:mc-us3  pci@9,600000:intr
memory-controller@2,400000         pci@9,600000:reg
memory-controller@2,400000:mc-us3  pci@9,700000
options                            pci@9,700000:devctl
pci@8,600000                       pci@9,700000:intr
pci@8,600000:devctl                pci@9,700000:reg
pci@8,600000:intr                  pseudo
pci@8,600000:reg                   pseudo:devctl
pci@8,700000                       scsi_vhci
pci@8,700000:devctl                scsi_vhci:devctl
pci@8,700000:intr

Most of these names are directories, so if you cd into /devices/pseudo directory, you will see all the software (hence pseudo) devices present in your system. Other directories will refer to various elements found on the system bus, for instance you can find a directory /devices/pci@9,600000/SUNW,qlc@2/ which will represent a built-in FC-AL Host Adapter which manages hard drives on my system.

Device instance numbers

As you know, it’s quite possible to have more than one device of the same kind in your system. Because of this, all the physical devices are mapped to instance numbers. Even if you have only one device of a particular kind, it will get an instance number. Numeration starts with 0.

For example, on Sun v490 there are 2 on-board gigabit network interfaces, and they’re referred to as ce0 and ce1. Similarly, all other devices are numbered and mapped.

All the physical device mappings to their instances are recorded in /etc/path_to_inst file. That’s the file used by Solaris to keep instance numbers persistent across reboots:

bash-3.00# more /etc/path_to_inst # #       Caution! This file contains critical kernel state
#
"/pseudo" 0 "pseudo"
"/scsi_vhci" 0 "scsi_vhci"
"/options" 0 "options"
"/pci@8,700000" 0 "pcisch"
"/pci@8,700000/ide@6" 0 "uata"
"/pci@8,700000/ide@6/sd@0,0" 1 "sd"
"/pci@8,600000" 1 "pcisch"



Unix Tutorial update: Reference page

Looking at this website access logs, I see how many people share the same problems and look for the same solutions, but use vastly different search queries to get to my posts.

I’ve decided to make your life easier, and have just launched a Unix Tutorial Reference page, which is an index of pages based on your searches. Most pages will have a basic introduction to the topic and provide further pointers to the solution posts.




How To: Use apt-get behind proxy

If you run your Ubuntu system behind a firewall and have to use proxy server for http and ftp access, then your apt-get on a newly installed Ubuntu system will probably not work.

To make it use proxy, simply set the http_proxy environment variable. Once you get it working (try something like apt-get update), you’ll probably want to add it to your .bashrc file.

Setting the http_proxy variable

Here’s how you set the variable:

bash$ export http_proxy=http://proxy:8080

If you’re required to use your username and password for your proxy, they can be specified this way. Obviously, port 8080 can and should be replaced with the valid port for your proxy server (sometimes it’s 3128):

bash$ export http_proxy=http://username:password@proxy:8080

See Also




Welcome!

H, and welcome to UNIX Tutorial – a future hub for all sorts of useful information on various UNIX systems.

The project is about to be launched by the end of August, so stay tuned! If you have any ideas/suggestions – please don’t hesitate to contact us immediately!