One of the students asked me about installing python2.7 on a redhat 6 system. Since I know the operating system depends on a particular version of python, I was immediately thinking about just upgrading the system to RHEL7, which would have the version of python required. But, happily, I’ve found that RedHat has provided a way to upgrade important systems. It has created a new channel called “RedHat Software Collections”. The beauty of these is that you can still use the regular package manager and that they won’t overwrite or conflict with system files. You need to enable the channel and install “scl-utils and scl-utils-build”. Then, the command to switch/see collections is scl. As an example,

[~]$ scl -l
devtoolset-3
python27
rh-java-common

Here’s an example of how it works.

[~]$ python -V
Python 2.6.6
[~]$ scl enable python27 bash
[~]$ python -V
python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
[~]$ printenv LD_LIBRARY_PATH
/code/Xilinx/Vivado/2014.2/lib/lnx64.o:/usr/lib64/root
[~]$ export LD_LIBRARY_PATH=/opt/rh/python27/root/usr/lib64:${LD_LIBRARY_PATH}
[~]$ python -V
Python 2.7.8
[~]$ exit
exit
[~]$ python -V
Python 2.6.6

When you first login to the system, you have the standard python installation of 2.6.6. Then, after you enable the python27 package, you get an error. For some reason, the script that sets things up isn’t setting LD_LIBRARY_PATH correctly. Above I set it manually. Then, you can see the newer version of python. The scl program actually opens a new shell with a new path. So after entering ‘exit’ to leave that shell, you’re back to how things were originally.

My first problem is, why isn’t LD_LIBRARY_PATH being set correctly? The scl program is just sourcing the file /opt/rh/python27/enable. Here are the contents of that file.

[python27]$ cat enable
export PATH=/opt/rh/python27/root/usr/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/opt/rh/python27/root/usr/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
export MANPATH=/opt/rh/python27/root/usr/share/man:${MANPATH}
# For systemtap
export XDG_DATA_DIRS=/opt/rh/python27/root/usr/share${XDG_DATA_DIRS:+:${XDG_DATA_DIRS}}
# For pkg-config
export PKG_CONFIG_PATH=/opt/rh/python27/root/usr/lib64/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}

After a little investigation, I found that the reason it wasn’t being set correctly is that I was overwriting it with my own .bashrc file. Once I fixed the setting there, everything worked as expected.

Now, as far as I can tell, all the students working on this system are going to want to use the newer version of python. So I want to set it up so that the scl command is automatically run. My solution was to create a file, called python27.sh in /etc/profile.d.

[profile.d]# cat python27.sh 
. /opt/rh/python27/enable

Now, anyone logging in will automatically get the new python. In the event that someone needs the old version of python, I made a simple disable script that should set things back. In /opt/rh/python27, create a file called disable.

[python27]# cat disable
export PATH=/usr/lib64/qt-3.3/bin:/usr/NX/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
unset LD_LIBRARY_PATH
unset MANPATH
# For systemtap
unset XDG_DATA_DIRS
# For pkg-config
unset PKG_CONFIG_PATH

This disable script isn’t perfect, as it just unsets LD_LIBRARY_PATH. But I think it will work for us.