Personalizando el ${PATH} a la OS X

Environment variables
"A set of dynamic named values that can affect the way running processes will behave on a computer. They can be said in some sense to create the operating environment in which a process runs.
For example, an environment variable with a standard name can store the location that a particular computer system uses to store temporary files—this may vary from one computer system to another."
-- from wikipedia [search: environment variable]

De las personalizaciones
Sucede que hace días he observado que en las cuentas unix que tenemos asignadas para el proyecto en el cual me encuentro involucrado, se firman otros usuarios que realizan diversas actividades que van desde instalaciones, monitoreo, programación, configuración y pruebas. Pero esto ha añadido una problematica ya que con los nuevos ingresos, vienen las personalizaciones de los ambientes y por ende, afectan las actividades de otros usuarios.

Generalmente los archivos que suelen modificar son el .profile (en HP-UX) o el .bash_profile y es que es en estos archivos donde se declaran las variables que pueden alterar el comportamiento de la consola de comandos (o para los más versados, la shell), por ejemplo variables para iniciar una base de datos de Oracle, incrementar el número de archivos abiertos hasta la ubicación de nuevos binarios.

Construir un nuevo ${PATH}
La variable en una consola UNIX donde se buscan los binarios por defecto es ${PATH}, los archivos deberán de contar con permisos de ejecución y su contenido será similar a lo siguiente:
andresaquino $> echo $PATH
.:/opt/local/sbin:/opt/local/bin:/Users/andresaquino/monopse:/usr/local/bin:/opt/local/bin:/opt/local/sbin:/opt/jython/bin:/opt/jmeter/bin:/opt/groovy/bin:/Users/andresaquino/.gem/ruby/1.8/bin:/Users/andresaquino/apps::/bin:/sbin:/usr/bin:/usr/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

Ahora bien, OS X implementa una solución bastante práctica (muy a la Gentoo Linux) para agregar nuevas rutas de ejecución, para ello se hace uso de una aplicación llamada path_helper y al ejecutarse construye un nuevo PATH así como un MANPATH (donde se ubican los manuales de usuario).
/etc/profile

Ahora bien, lo que necesitábamos era implementar una solución que involucrara los tres sabores de unix con los que trabajamos (HP-UX, Linux y Darwin), así que tomé la idea de OS X y la implementé en sh. Esto quiere decir que era necesario contar con archivos donde se almacenaran los binarios por aplicación y un directorio donde agruparlos, así como tener la posibilidad de no modificar el perfil principal sino era necesario, así que el panorama inicial era mas o menos el siguiente:
andresaquino $> tree ~/paths.d/
/Users/andresaquino/paths.d/
├── bscsapps
├── gems
├── groovy
├── java14
├── java15
├── java16
├── jmeter
├── jruby
├── jython
├── locals
├── monopse
├── oracle
├── ports
└── soya

0 directories, 14 files          

Y el contenido de uno de estos archivos es:
andresaquino $> cat java15 
/System/Library/Frameworks/JavaVM.framework/Versions/1.5
/opt/java-1.5.0-sun
/opt/java/java1.5
/opt/java1.5

Para poder entonces modificar el ${PATH} sin necesidad de estar haciendo cambios al perfil principal, escribí el siguiente fragmento, el cual a grandes rasgos pretende hacer lo siguiente:
  1. Verificar que exista el directorio paths.d y que no se encuentre vacío.
  2. Por cada archivo existente en el directorio paths.d, verificar que:
    1. Contenga información
    2. No incluya lineas de binarios de JAVA
    3. Entregar un ${PATH} limpio
  3. Agregar el nuevo path a la variable principal ${PATH}
Veamos:

# Define a execution unix path reading each file in paths.d
localpaths () 
{
  LPATH=

  # if not exist or is empty, exit 
  [ ! -d ${HOME}/paths.d ] || [ -z "$(ls -A ${HOME}/paths.d)" ] && return 0

  for pathfile in ${HOME}/paths.d/*
  do
    # empty file
    [ ! -s ${pathfile} ] && continue
    
    # include java path
    grep -q java ${pathfile} && continue 

    # for each file, get paths and add to execution path
    for eachpath in $(cat ${pathfile})
    do
      # get one line (path) and verify: is this a directory? 
      eachpath="$(eval echo ${eachpath} | sed -e 's/ *//g')"
      [ ! -d ${eachpath} ] && break 

      LPATH=${eachpath}:${LPATH}
      logto "Adding new path: ${eachpath}"
    done
  done

  # User binary  
  [ -d ${HOME}/bin ] && LPATH=${HOME}/bin:${LPATH}

  LPATH=.:${LPATH}
  PATH=${LPATH}:${_PATH}

}

Lo que sigue es cambiarlo por el .profile o por el .bash_profile y observar los resultados, los cuales deberán ser similares a los siguientes:
Loading new environment



Referencias


buen camino!

Popular Posts