Linux gperf C and C++ command line processing programming tutorial

Posted on in Categories C Programming, Linux, UNIX last updated July 29, 2007

GNU ‘gperf’ generates perfect hash functions. If a long option shows an argument as mandatory, then it is mandatory for the equivalent short option also. Use this tutorial for effective command-line processing in your C/C++ code:

Command-line processing is historically one of the most ignored areas in software development. Just about any relatively complicated software has dozens of available command-line options. In fact, it’s not uncommon to find hundreds of lines of if-else statements coded to process user input, and maintenance of such legacy code becomes a time-consuming affair even for seasoned programmers. In such circumstances, most C developers commonly go for a rather long (and often nested) if-else statement with ANSI C library functions such as strcmp, strcasecmp, and strtok …

The gperf utility is tuned to quickly generate a perfect hash for small to medium datasets. But gperf has other applications, as well. In fact, it’s the tool of choice of maintaining perfect hashes for language keywords in GNU compilers, and recent advances allow you to work with larger datasets. So, consider making gperf part of your next development project.

GNU perfect (gperf) hash function generator makes short work of complex input strings

Linux add ethtool duplex settings to a network card permanently

Posted on in Categories Linux, Networking, Tips, Ubuntu Linux last updated July 16, 2007

I have already written about how to find and change your network interface speed (NIC), duplex or auto negotiate settings on Linux using ehttool command line options.

However, these settings are not permanent. If you reboot the system or if you just
need to upgrade/downgrade your port speed, run the ehtool command once your port change by network administrator. (If you want to read about how to make Windows 2000/2003 server port speed change, read my previous article.)

Changing your Network Interface Speed, Duplex or Auto Negotiate settings on Red Hat Linux

To set the interface speed, duplex or auto negotiation on Linux system boot up (make settings permanent), you need edit /etc/sysconfig/network-scripts/ifcfg-eth0 file for eth0 interface. This file used by Red Hat enterprise Linux, Fedora core, Cent Os etc.

Open the file:
# vi /etc/sysconfig/network-scripts/ifcfg-eth0

Append following line:
ETHTOOL_OPTS="speed 100 duplex full autoneg off"

Save and close the system. It will set the eth0 device to 100Mbs, full duplex, with the auto negotiation off at boot time. You can simply restart the networking (it will disconnect all ssh or ftp session) or restart the server. Depend upon traffic and load it may take upto 1 minute to setup a new port speed:
# /etc/init.d/network restart

If you want 1000Mbs set line as follows:
ETHTOOL_OPTS="speed 1000 duplex full autoneg off"Update: if above command failed to work for 1000Mbps use following command (see below in comment sections for discussion) :ETHTOOL_OPTS="speed 1000 duplex full autoneg on"

Debian or Ubuntu Linux permanent settings

Under Debian or Ubuntu Linux just create a script as follows:
# vi /etc/init.d/100Mbs
$ sudo vi /etc/init.d/100Mbs
Append following lines:
SPEED="100 duplex full"
case "$1" in
echo -n "Setting eth0 speed 100 duplex full...";
$ETHTOOL -s $DEV speed $SPEED;
echo " done.";;
exit 0
Save and close the file. Setup executable permission:
# chmod +x /etc/init.d/100MbsOR$ sudo chmod +x /etc/init.d/100Mbs

Now run script when Debian or Ubuntu Linux boots up. Use update-rc.d command install System-V style init script links:# update-rc.d 100Mbs defaultsOR# sudo update-rc.d 100Mbs defaultsOutput:

 Adding system startup for /etc/init.d/100Mbs ...
   /etc/rc0.d/K20100Mbs -> ../init.d/100Mbs
   /etc/rc1.d/K20100Mbs -> ../init.d/100Mbs
   /etc/rc6.d/K20100Mbs -> ../init.d/100Mbs
   /etc/rc2.d/S20100Mbs -> ../init.d/100Mbs
   /etc/rc3.d/S20100Mbs -> ../init.d/100Mbs
   /etc/rc4.d/S20100Mbs -> ../init.d/100Mbs
   /etc/rc5.d/S20100Mbs -> ../init.d/100Mbs

Reboot the system to take effect or just type scrit name:
# /etc/init.d/100Mbs startOR$ sudo /etc/init.d/100Mbs start

See also:

Linux or UNIX: HowTo Find Out or Display The Ethernet Address (MAC)

Posted on in Categories FreeBSD, Linux, Networking, OpenBSD, OS X, Solaris, UNIX, Windows server last updated March 31, 2012

Media Access Control (MAC) address is a unique identifier attached to most networking devices (such as router, Ethernet cards, servers, nas devices, switches and so on).

This blog posts demonstrates how to get the Media Access Control (MAC) address for an ethernet adapter under Linux, Unix, Apple OS X, and *BSD operating systems using command line options.

How BASH Shell Command Search Sequence Works

Posted on in Categories CentOS, Debian Linux, FreeBSD, Howto, Linux, Shell scripting, Suse Linux, UNIX last updated March 6, 2015

This article was organically contributed by monk.

HASH tables and PATH is not the first method locating your program or executable files on a Linux or Unix-like systems. Your program can be a shell function or builtin command or an alias. Here is the complete sequence adopted by BASH shell to execute your command:

  1. Before a command is executed REDIRECTION is done. Then following sequence used by SHELL
  3. Parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable
  4. Shell FUNCTION
  5. BUILTIN command
  6. HASH tables
  7. PATH variable
  8. If everything fails, you see command not found error message.


Try out the following simple examples to understand the SHELL sequence

a) Create your own bin directory and add to a PATH:
$ mkdir ~/bin
$ export PATH=$PATH:~/bin

b) Create a shell function called hello:
$ function hello() { echo "Hello from function()" ; }

c) Create an alias called hello:
$ alias hello='echo Hello from alias'

d) Create a shell script called hello in /home/you/bin directory (which is added to your PATH)
$ echo 'echo Hello from script' > ~/bin/hello
$ chmod +x ~/bin/hello

e) Let us test it:
Now, you have three different commands with the same name (i.e. hello). Which one will execute first? Type the following commands at command prompt:
$ type hello
$ hello

Sample outputs:

Hello from alias

f) Remove an alias and run hello again:
$ unalias hello
$ hello

Sample outputs:

Hello from function()

g) Remove a shell function hello and run hello again:
$ unset hello
Sample outputs:

Hello for script

h) Remove a shell script hello and run hello again:
$ rm ~/bin/hello
$ hello

Sample outputs:

bash: /home/monk/bin/hello: No such file or directory

You just removed the hello script but Bash shell still looking hello program at /home/monk/bin/hello location. What is going on here? The answer is pretty simple, “HASH table. The shell is looking for a cached PATH entry for hello script. To verify this just type the hash command to see HASH table:
$ hash
Sample outputs:

hits    command
1    /bin/rm
1    /bin/cat
2    /usr/bin/print
3    /home/monk/bin/hello
1    /usr/bin/man

Your SHELL remembered path settings names in HASH table. There is an easy solution, just clear hash table and see the effect again:
$ hash -r
$ hello
Sample outputs:

bash: hello: command not found

I hope this basic explanation will help to all new users out there. As a result next time you run a command remember shell goes through quite a complicated sequence of operations to process your request.

Continue reading the second part of “How Linux or UNIX Understand which program to run” series (this is part I):

  • PART I : How Linux or UNIX Understand which program to run
  • PART II : An example: How shell Understand which program to run

How Linux or UNIX Understand which program to run – PART I

Posted on in Categories Debian Linux, File system, Howto, Linux, Shell scripting, Solaris, Suse Linux, Sys admin, Tips, Ubuntu Linux, UNIX last updated August 29, 2007

This article was organically contributed by monk.

When you are logged in to a Linux server and you type a command. It is the responsibility of the shell to interpret your command. Here I will explain how BASH shell finds out which program to run. The method used by SHELL is straightforward but often creates confusion for new Linux user/admins/Interns.

Remember your shell deals with different commands and command line options to process your request.
For example:

  1. Internal commands aka shell builtin command (such as set)
  2. External commands (such as clear, date)
  3. Aliases (such as alias rm=’rm -i’)
  4. Command substitutions ( such as echo “Today is $(date)”)
  5. Functions
  6. Pipes ( such as cat /etc/passwd | wc -l)
  7. I/O redirection (such as cat /etc/passwd > /tmp/names)

As you can see, SHELL has to do many things before it can find the correct executable file for you. For example, when you type single command date; SHELL will locate date command for you. Then it spawns (forks) a new process and “execs” the date command. Please note that discussion related forks and kernel is beyond the scope of this document (see nice explanation by Tony @ How shells call other programs). Here you just want to understand how Linux knows which program to run.

Shell uses PATH variable

Your shell uses the environment variable called PATH to locate commands. Just type following command to display your current PATH:

$ echo $PATH


The variable PATH defines search path for commands. As you can see, PATH holds a colon-separated list of directories in which the shell looks for commands. Returning to the date example, when you type date command, shell will start with the directory on left (i.e. /usr/local/bin) side of PATH variable and checks to see if there is date command executable file. If executable file found, shell will execute date command. If command cannot be located at all in all directories then you will see command not found error message. BASH shell use following sequence to execute command (for example purpose, we will use date command):

  1. If there exists a shell FUNCTION date() execute it and stop.
  2. If there exists a shell builtin date command, execute it and stop
  3. If the date is neither a shell function nor a builtin then BASH searches in HASH tables. If there exists an entry for date command execute it and stop.
  4. Finally, if date does not exist in HASH tables, it will search using PATH variable.
  5. If above all method fails then SHELL will return error “Command not found” and always exit with 127 status code.

However, things started to get complicated if it is a shell script, the SHELL does exactly the same thing (as mentioned above), but the exec fails, which causes the shell to read the script and interpret it.

What is a HASH table?

A HASH table is nothing but some sort of caching mechanism to speed up things. For each command, the full file name of the command is determined by searching the directories in $PATH variable and remembered by shell in HASH table. Just type hash command and it will display the all remembered directory name:
$ hash

hits    command
5    /usr/bin/chsh
1    /usr/bin/man
1    /bin/ls

Related shell commands
To solve a command searching mysteries Linux/SHELL offers couple of commands.

type command

Tells whether command is an alias, function, buitin command or executable command file. To be frank type command indicate how it would be interpreted if used as a command name. General syntax:
type {command-name}

$ type -a ls

ls is aliased to 'ls --color=auto'

$ type date

date is hashed (/bin/date)

$ type dirs

dirs is a shell builtin

$ type if

if is a shell keyword

$ type getip

getip is a function
getip ()
lynx --dump 'http://localhost:81/getip'

which command

Use to locate a command in a PATH.
$ which ls


Continue reading the second part of “How Linux or UNIX Understand which program to run” series (this is part I).

  • PART I : How Linux or UNIX Understand which program to run
  • PART II : An example: How shell Understand which program to run

Updated for accuracy by Vivek. This article almost rewritten to fix typos.

Solaris tar command to backup data on tape device

Posted on in Categories Howto, Solaris, Sys admin, Tips, UNIX last updated March 11, 2008

Tar name come from Tape ARchiver. It is both a file format and the name of the program used to handle such file. Tar archive files have names ending in “.tar”. If an archive is compressed, the compression program adds its own suffix as usual, resulting in filename endings like “.tar.Z”, “.tar.gz”, and “.tar.bz2”. Tar doesn’t require any particular filename suffix in order to recognize a file as an archive. Tar was originally created for backups on magnetic tape, but it can be used to create tar files anywhere on a filesystem. Archives that have been created with tar are commonly referred to as tarballs.

Create a new set of backup

To create a Tar file, use tar command as follows:
# tar cvf /dev/rmt/X file1 file2 dir1 dir2 file2 …

  • c – Create a new files on tape/archive
  • v – verbose i.e. show list of files while backing up
  • f – tape device name or file

For example, backup /export/home/vivek/sprj directory to tape device /dev/rmt/0, enter
# tar cvf /dev/rmt/0 /export/home/vivek/sprj/
Remember c option should only use to create new set of backup.

Appending or backing up more files to same tape using tar

tar provides r option for appending files to tape. For example to backup /data2/tprj/alpha1 files to same tape i.e. appending files to a first tape device:
# tar rvf /dev/rmt/0 /data2/tprj/alpha1/*

  • r – append files to the end of an archive/tape

List files on a tape using tar command

To display file listing of a first tape use tar as follows:
# tar tvf /dev/rmt/0
To listing the Contents of a Stored Directory (for example wwwroot directory):
# tar tvf /dev/rmt/0 wwwroot

  • t – list the contents of an archive/tape

Retrieve / restore tape backup taken with tar

1) Use tar command as follows to retrieve tape drive backup to current directory:
(a) Change directory where you would like to restore files:
# cd /path/to/restore
# pwd

(b) Now, do a restore from tape:
# tar xvf /dev/rmt/0

To specify target directory use –C option

Restore everything to /data2 directory:
# tar xvf /dev/rmt/0 –C /data2
To retrieve directory or file use tar as follows:
# tar xvf /dev/rmt/0 tprj
Note that Solaris tar command is little different from GNU tar, if you wish to use gnu tar with Solaris use command gtar. Gnu tar accepts same command line options plus bunch of additional options :)

See Sun Solaris tar man page and tapes ~ creates /dev entries for tape drives attached to the system.