bash: Find Out the Version of Your Unix Shell

bash (Bourne Again SHell) comes with pretty much every Unix-like OS these days. If you ever wonder what exact version of bash shell you have on your system, here’s how you find out: just use the –version parameter in the command line.

Using /bin/bash to tell its version

On RedHat Linux, this is how it might look:

bash-2.05b$ /bin/bash --version
GNU bash, version 2.05b.0(1)-release (i386-redhat-linux-gnu)
Copyright (C) 2002 Free Software Foundation, Inc.

On Solaris 10 (one of the latest OpenSolaris builds, actually), it’s a very similar output as well:

-bash-3.2$ /bin/bash --version
GNU bash, version 3.2.25(1)-release (i386-pc-solaris2.11)
Copyright (C) 2005 Free Software Foundation, Inc.

If you don’t know the location of bash binary

The first and most obvious thing is to use which command to confirm the possible location of your bash binary.

On Linux:

 bash-2.05b$ which bash
/bin/bash

In Solaris:

-bash-3.2$ which bash
/usr/bin/bash

As you can see, this command returns you the full path to a binary, bash in our case. Once you know the full binary name, run it like explained in the first part of this post to confirm the version. Bear in mind that which command does not always return a result.

If this didn’t work, a more sophisticated way to confirm the version of bash on your RedHat Linux system is to use rpm:

bash-2.05b$ rpm -qa | grep bash
bash-2.05b-41.4

This commands queries the RPM database of your RedHat Linux and confirms which version of the bash RPM package is installed, which naturally matches the version of the bash itself.




sudo tutorial

sudo allows you to run a Unix command as a different user. Using /etc/sudoers file to confirm what privileges are available to you, this command effectively elevates your access rights, thus allowing you to run commands and access files which would otherwise be not available to you.

How sudo command works

The real and effective user id (uid) and group id (gid) are set to match those of the target user as specified in /etc/sudoers file (the safest way to change this file is to use the visudo command – check out the visudo tutorial). The way you use sudo is simple enough: you run this command and specify a command line you’d like to run with the privileges of a different user. Before the requested command is run, you are asked to confirm your identify by providing your user password.

id command, which shows you who you are in your Unix system (user id, user name, group id and other Unix groups you’re member of), is the easiest way to demonstrate how your privileges are elevated. Truly, you become a different Unix user:

$ id
uid=1000(greys) gid=33(www-data) groups=33(www-data),113(admin)
$ sudo id
Password:
uid=0(root) gid=0(root) groups=0(root)

Using sudo in interactive mode

Sometimes you’ll want to run many commands as a different user. Most common scenario for this presents in default sudo installation: you’re encouraged to never become root, but instead use sudo to run commands as root.

When you want to use sudo in interactive mode, you run sudo with the -i parameter. This parameter causes sudo to imitate the initial login sequence – as if you simply log into your Unix system under a different user. The shell of this user is executed, and then you get the command prompt – anything you run after this will be run as the user granted to you by sudo:

$ id
uid=1000(greys) gid=33(www-data) groups=33(www-data),113(admin)
$ sudo -i
Password:
# id
uid=0(root) gid=0(root) groups=0(root)
# groups
root

Editing files with sudo

If instead of running some command as a different user you just want to edit some file which belogs to this user, then you will like the -e option for sudo. When using sudo to edit files, instead of a Unix command you specify the file you’d like to edit:

$  sudo -e /etc/passwd



Find Compiler Version in Unix

Finding the compiler version in your Unix system should be the first step before you attempt to compile any package from its source codes. In fact, if you’re familiar with the common compilation routine, the configure script which you run to generate the Makefile before compiling anything does exactly that – it finds out which compilers (if any) you have installed on your system, and confirms their versions and capabilities.

If you want to find the compiler version yourself, here’s what you do:

1) Confirm which compiler you’re looking at

Most likely, it will be gcc, but since GCC isn’t a GNU C Compiler anymore, but a GNU Compiler Collection, it can stand for any programming language from this suite. Here they are, just so that you know (a binary of each compiler is shown in bold):

gcc – GNU project C and C++ compiler
g++ – GNU project C and C++ compiler
gcj – GNU Compiler for Java
g77 – GNU project Fortran 77 compiler
gnat – GNU Ada Translator

2) Find where your compiler is installed

You have a pretty good chance of finding gcc binaries right under /usr/bin directory on most modern systems. Some older Unix distros will not have GCC installed by default, others like recent versions of Solaris and OpenSolaris, will have gcc under a different location. In Solaris 10, gcc binaries are under /usr/sfw/bin directory.

If the gcc binary isn’t found, consider looking for the file using the find command, or query software repository to confirm if it’s installed or now.

3) Run the compiler to find out its version

Most compilers will give you their version if -v option is specified:

$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release x86_64-linux-gnu
Thread model: posix
gcc version 4.1.2 (Ubuntu 4.1.2-0ubuntu4)

See also:




tee: Replicate Standard Output

Now and then I come across a situation when I need to run a script or a Unix command and would like to not only see the output of it on the screen, but also save this output to some log file. Redirecting the standard output using standard Unix stream redirection isn’t always useful because your output will either be shown to you, or sent to the file – but not both at the same time

tee command

That’s where the tee command becomes really useful. You pipe your output to this command, and let it take care of the rest.

Here’s how you use it:

greys@simplyunix:~$ uname -a | tee /tmp/uname.txt
Linux simplyunix.com 2.6.16.29-xen #1 SMP Sun Sep 30 04:00:13 UTC 2007 x86_64 GNU/Linux
greys@simplyunix:~$ cat /tmp/uname.txt
Linux simplyunix.com 2.6.16.29-xen #1 SMP Sun Sep 30 04:00:13 UTC 2007 x86_64 GNU/Linux

What happens is that tee replicates the standard output to both your session and the specified file.

See also:




script: Save Your Session Log

If you ever need to save the history of your Unix shell session, one of the easiest ways to do it is to use the script command, found in most Unix systems.

Simply provide the file name for your log as a command line parameter:

$ script /tmp/unix-session.log

After starting the command, you’ll be able to do whatever you want, and once you’re done you can use the standard Ctrl+D to end the session recording. The generated log file will have both the commands you have typed during your session and the output generated by these commands.

Your session log with also include the timestamps marking the start and the finish of your recording.

Here’s a sample session showing you how you use the script command:

$ script /tmp/unix-session.log
Script started, file is /tmp/unix-session.log
$ uname -a
Linux simplyunix.com 2.6.16.29-xen #3 SMP Sun Oct 15 13:15:34 BST 2006 x86_64 GNU/Linux
$ exit
Script done, file is /tmp/unix-session.log

Now, if we were to cat the log file generated in this example, we’d see the following:

$ cat /tmp/unix-session.log
Script started on Tue Nov 20 16:48:08 2007
$ uname -a
Linux simplyunix.com 2.6.16.29-xen #3 SMP Sun Oct 15 13:15:34 BST 2006 x86_64 GNU/Linux
$ exit
Script done on Tue Nov 20 16:48:12 2007

Have you got a better way to save your sessions? Let me know! (saving logs from gnome-terminal and Putty doesn’t count, mind you!)




Unix File Types

In Unix systems, there are 6 file types. Below I will give a very short description of each.

How to find out the type of file in Unix

The first and most obvious way to confirm the type of a particular file is to use the long-format output of ls command, invoked by the -l option:

$ ls -l * 
 -rw-r--r-- 1 greys greys       1024 Mar 29 06:31 text

The very first field of such output is the file type and access permissions field, I’ll cover them in a separate post in the future. For now, just concentrate on the first character in this field. In this particular case, it’s “-“, which means it’s a regular file. For other file types, this character will be different.

Regular file

This is the most common type of a file in Unix. Being a plain collection of bytes with arbitrary data. There’s nothing mysterious about this type. Most of the files you will ever work with are regular.

In long-format output of ls, this type of file is specified by the “-” symbol.

Directory

This is a special type of a file in Unix, which only contains a list of other files (the contents of a directory). You don’t work with directories directly, instead you manage them with standard commands provided with your OS. The whole directory structure of your Unix system is made of such special files with directory content in each of them.

In long-format output of ls, this type of file is specified by the “d” symbol:

$ ls -ld * 
 -rw-r--r-- 1 greys greys	1024 Mar 29 06:31 text
 drwxr-xr-x 2 greys greys	4096 Aug 21 11:00 mydir

Special Device File

This type of files in Unix allows access to various devices known to your system. Literally, almost every device has a special file associated with it. This simplifies the way Unix interacts with different devices – to the OS and most commands each device is still a file, so it can be read from and written to using various commands. Most special device files are owned by root, and regular users cannot create them,

Depending on the way of accessing each device, its special device file can be either a character (shown as “c” in ls output) or a block (shown as “b”) device. One device can have more than one device file associated, and it’s perfectly normal to have both character and block device files for the same device.

Most special device files are character ones, and devices referred by them are called raw devices. The simple reason behind such a name is that by accessing the device via its special device character file, you’re accessing the raw data on the device in a form the device is ready to operate with. For terminal devices, it’s one character at a time. For disk devices though, raw access means reading or writing in whole chunks of data – blocks, which are native to your disk. The most important thing to remember about raw devices is that all the read/write operations to them are direct, immediate and not cached.

Block device file will provide similar access to the same device, only this time the interaction is going to be buffered by the kernel of your Unix OS. Grouping data into logical blocks and caching such blocks in memory allows the kernel to process most I/O requests much more efficiently. No longer does it have to physically access the disk every time a request happens. The data block is read once, and then all the operations to it happen in the cached version of it, with data being synced to the actual device in regular intervals by a special process running in your OS.

Here’s how the different types of special device files look in your ls output:

$ ls -al /dev/loop0 /dev/ttys0
brw-rw---- 1 root disk 7,  0 Sep  7 05:03 /dev/loop0
crw-rw-rw- 1 root tty  3, 48 Sep  7 05:04 /dev/ttys0

Named Pipe

Pipes represent one of simpler forms of Unix interprocess communication. Their purpose is to connect I/O of two Unix processes accessing the pipe. One of the processes uses this pipe for output of data, while another process uses the very same named pipe file for input.

In long-format output of ls, named pipes are marked by the “p” symbol:

$ ls -al /dev/xconsole
prw-r----- 1 root adm 0 Sep 25 08:58 /dev/xconsole

Symbolic Link

This is yet another file type in Unix, used for referencing some other file of the filesystem. Symbolic link contains a text form of the path to the file it references. To an end user, symlink (sort for symbolic link) will appear to have its own name, but when you try reading or writing data to this file, it will instead reference these operations to the file it points to.

In long-format output of ls, symlinks are marked by the “l” symbol (that’s a lower case L). It also show the path to the referenced file:

$ ls -al hosts
lrwxrwxrwx 1 greys www-data 10 Sep 25 09:06 hosts -> /etc/hosts

In this example, a symlink called hosts points to the /etc/hosts file.

Socket

A Unix socket (sometimes also called IPC socket – inter-process communication socket) is a special file which allows for advanced inter-process communication. In essence, it is a stream of data, very similar to network stream (and network sockets), but all the transactions are local to the filesystem.

In long-format output of ls, Unix sockets are marked by “s” symbol:

$ ls -al /dev/log
srw-rw-rw- 1 root root 0 Sep  7 05:04 /dev/log

That’s it. Hope this gave you a better idea of what file types you can find working on your Unix system. I’ll obviously expand relevant topics in the future. Let me know if there’s anything in particular you’d like me to concentrate on!




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




Ubuntu: Using Sudo to Grant User Privileges

If you have used your fresh Ubuntu install for longer than half an hour, chances are that you’ve discovered the sudo command already.

sudo allows certain users to execute a command under another user’s privileges. Most commonly, using sudo implies running a command as a superuser, but the approach works equally well for allowing you to inherit a user ID (uid) and group ID (gid) of any user on the system.

To gain access, a password is asked, and by default it is your password, and not the password of a user you’re trying to run a command as. This allows for the system’ s administrator to effectively manage user privileges without having any user share their password.

sudo is based off the /etc/sudoers file, which should be edited by root employing the visudo command. WARNING: although /etc/sudoers file is a regular text which root can edit manually, ONLY visudo way of updating it is recommended, as this command, apart from editing capabilities, also does a syntax check of the changes before applying them to prevent user privilege related disasters.

If you want to grant superuser privileges to a particular user, the following line should be added to the /etc/sudoers file (just type visudo to invoke the editor):

greys ALL=(ALL) ALL

In this example, greys is the username.

Related books

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

ubuntu-kung-fu-practical-guide
Ubuntu Kung Fu




Allow Incoming TCP Connections for X11 on a RedHat (RHEL4) System

Starting with RHEL4, the system only accepts local (socket-based) X11 server connections. This means that if you go to another Unix server and try forwarding X11 output by using DISPLAY variable to point to your RHEL4 box, it will no longer work.

Enabling TCP connections to X11

In order to make your RHEL4 system accept TCP connections for X11, here’s what you need to do:

In /etc/X11/gdm/gdm.conf, uncomment the

#DisallowTCP=true

line and change it to

DisallowTCP=false

That’s it! Restart gdm and enjoy!




How To: Find Out the Release Version of Your UNIX

Different UNIX-like operating systems store information about their release versions differently. If you know what OS you have, but not sure about the version, then here’s how you can find out:

RedHat Linux

bash-3.1$ cat /etc/redhat-release
Red Hat Enterprise Linux Client release 5 (Tikanga)

Ubuntu Linux

bash-3.1$ cat /etc/issue
Ubuntu 6.10 n l

SUSE Linux

~> cat /etc/SuSE-release
SUSE Linux Enterprise Desktop 10 (x86_64)
VERSION = 10

Sun Solaris

bash-2.03$ cat /etc/release Solaris 8 2/04 s28s_hw4wos_05a SPARC Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. Assembled 08 January 2004

See Also