Useful Shell Function pathmunge

When I wrote a function that updated the PATH environment variable to include a new directory path in its set of values I had named it “addtopath”, and “addtopathhigh” when prepending such directory. I was tweaking the /etc/profile file in Red Hat Enterprise Linux 5.3 when I saw this pathmunge function. It does the same:

pathmunge () {
  if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
     if [ "$2" = "after" ] ; then
        PATH=$PATH:$1
     else
        PATH=$1:$PATH
     fi
  fi
}

The difference, is that it both prepends and appends the PATH variable with the given argument ($1). The second argument controls whether it is an append operation when it is passed the value “after”, otherwise, it just prepends the given path to PATH’s value (analogous to the addtopathhigh function, which prepends the directory to the value and thus makes the added path with HIGHer priority in the search path, that was the reason why I named it that way).

In order to maintain it standard with RHEL I decided to adopt this function. Same name. But I improved it. The new definition expands the variables with curly braces, and after the pre/append it also sanitizes it by cleaning any preceding or trailing semi-colons for the basic case when the PATH variable had an empty value prior to the “munging”.

Here it is:

pathmunge () {
  if ! echo "${PATH}" | /bin/egrep -q "(^|:)$1($|:)" ; then
     if [ "$2" = "after" ] ; then
        PATH="${PATH}:${1}"
     else
        PATH="${1}:${PATH}"
     fi
     PATH="${PATH#:}"
     PATH="${PATH%:}"
  fi
}

 

Command Example for useradd

The useradd command is a tool that provides sysadmins with the capability of adding new users (a.k.a. logins) to the system. The generic form of the command is this:

useradd -c 'COMMENT' -d 'HOME' -m -p 'CRYPT_STRING' -s 'SHELL' LOGIN
  • COMMENT is used generally for user information such as full name, phone number etc.
  • HOME is the home folder e.g. /home/user.
  • CRYPT_STRING string generated by the crypt(3) function (libcrypt, a component of glibc, the GNU C Library).
  • SHELL is the default shell for the user.
  • LOGIN is for the new username in question.

The -m option creates the user’s home directory if it does not exist.

Example:

useradd -c 'John Doe' -d /home/johndoe -m -p 'ABiELdbxGY2fY' -s '/bin/ksh' johndoe

John Doe just got himself a new account with the /home/johndoe home/login directory, created (-m) if not present, with CRYPT_STRING ‘ABiELdbxGY2fY’ generated by the crypt(3) function for the (simplest and unbelievably most commonly used) password ’123456′ with salt ‘AB’. The default login shell for this account is ksh (-s ‘/bin/ksh’). And last, the username, johndoe.

Go on and create some users on your grid.

Add CDROM or ISO Packages to Red Hat Enterprise Linux 5.7

Red Hat generally provides a stable Linux distribution in its currently supported releases. And one might want to only use the packages that came along with the distribution media i.e. a cdrom or an .iso file containing that cd’s image.

To be able to use a CD’s or .iso file’s packages in RHEL (Red Hat Enterprise Linux) 5.7, create this file in /etc/yum.repos.d/:

[user@localhost yum.repos.d]$ cat redhat_cdrom.repo
[redhat_cdrom]
name=Red Hat Enterprise Linux $releasever - CD-ROM
baseurl=file:///media/rhel/Server
enabled=1
gpgcheck=1
gpgkey=file:///media/rhel/RPM-GPG-KEY-redhat-release

This is assuming you had mounted the cdrom or the distribution’s .iso file to the /media/rhel directory.

Then do:

# yum update

And then pick up the desired software and install it:

# yum install <packages>

That is all.

FreeBSD Software Search and Management

FreeBSD has its Package and Ports software scheme. Both have dependency check and handle the automatic installation(s) when there is (are) any.

First of all, if you want to have a program but you do not have a clue of what is its name, try searching for it in popular FOSS sites such as Freecode (formerly known as freshmeat.net) etc. If you know the name and want to perform a search for it on the system you can do:

# whereis lsof
lsof: /usr/ports/sysutils/lsof

or:

# echo /usr/ports/*/*lsof*
/usr/ports/sysutils/lsof

The latter will also include matches found in /usr/ports/distfiles/.

Generally, the ports directory structure is inside the /usr/ports directory.

You can also use the handy Ports Collection’s built-in search mechanism, by cd‘ing to the /usr/ports directory and executing:

# make search name=program(port)-name

The system search above is for the FreeBSD Ports facility. We will come back to it shortly.

Packages are convenient as they are pre-compiled versions of applications. As such, they have the primary advantage of not imposing the awareness and compilation setup work (as when any tweak is desired), but you have to accept a software that was compiled with a very simple configuration as it must be able to execute smoothly in many platforms. Another advantage (if you considered the latter as such ;)) is that the compressed archive is a lot smaller than the source code archive. You handle packages with simple commands such as pkg_add, pkg_info, pkg_version, pkg_delete etc.

Ports, on the other hand, are a set of files (Makefile, patch files etc.) that make the source code for applications to be ported to (able to compile in and, hence, function correctly in) the FreeBSD realm.

To have compiled software is more secure and you have the control of the application aspects, including the ability to turn features on or off during compilation. The port’s corresponding source code archive (known as the distfile) is larger than a correspondent (pre-compiled) package for the software, though. Nevertheless the many benefits it brings, like security, source code availability, and compiling for the architecture make it the best choice for a handful of people e.g. developers or folks that just appreciate one of the many advantages listed.

So, we will cover a bit of Ports usage. For more information on Package usage in FreeBSD go to its official handbook documentation.

In order to be able to use the Ports facility you must first get the Ports Collection:

# csup -L 2 -h cvsup.FreeBSD.org /usr/share/examples/cvsup/ports-supfile

Instead of the value for the -h option above, choose a mirror near you.

The handbook also shows the sequence of menu options needed to install it from the installation media but as it installs the old (as of the release) Ports Collection you should use the internet way as stated above and also on the handbook.

The Ports Collection is comprised of a set of Makefiles, patches and description files, divided up into port skeletons (one skeleton is a port) each of which is a minimal set of files containing instructions on how to build (compile) the source code, but does not include the actual source code.

With an Internet connection already setup, go to the port directory e.g. for lsof:

# cd /usr/ports/sysutils/lsof

and (also as root) execute make, make install, and then, as advised by the handbook, make clean (temporary files used during compilation). To run all of them with only one command you can just run make install clean – this will do all the work for you: download the distfile, uncompress, build and install it and then clean its temporary compilation files.

The following passage from the handbook (section on ports usage) is very important for those that do not have an Internet connection up all the time:

For users which cannot be connected all the time, the make fetch option is provided. Just run this command at the top level directory (/usr/ports) and the required files will be downloaded for you. This command will also work in the lower level categories, for example: /usr/ports/net. Note that if a port depends on libraries or other ports this will not fetch the distfiles of those ports too. Replace fetch with fetch-recursive if you want to fetch all the dependencies of a port too.

Note: You can build all the ports in a category or as a whole by running make in the top level directory, just like the aforementioned make fetch method. This is dangerous, however, as some ports cannot co-exist. In other cases, some ports can install two different files with the same filename.

For more activities on Ports, like changing the Default Ports Directories, Reconfiguring, Upgrading or Removing Installed Ports, consult the handbook section on ports usage.

The Ports Collection will use disk space over time. Always remember to make clean while inside the relevant directory, or simply portsclean -C (in any directory). To remove all the distfiles not referenced by any port, execute portsclean -D, or portsclean -DD to delete the ones not referenced by any port currently installed on your system. portsclean is a part of the portsupgrade suite (also explained by the handbook section on ports usage which makes numerous more tips not present in this article available!).

Welcome to FreeBSD!

Bash Pattern Matching Operator

GNU Bash (4.2 as of this post)’s manual page says that its pattern matching operator =~

value =~ pattern

uses the ERE (Extended Regular Expression syntax) specification used by regex(3) which is the POSIX 1003.2 regular expressions format. Also, =~ has the same precedence as the == and != operators.

This is documented in the SHELL GRAMMAR section – Compound Commands – [[ expression ]].