libnsss_map library

Last week I was working on libnss_map, aNSS library module to map user credentials to existent user in the system. This module is intended to be used in high virtualized environment like cloud computing or embedded systems which require a lot of users.

When a new user has been authenticated by PAM or other authentication mechanism, then the nss_map module create a virtual user when credentials mapped to an existent user. For example, suppose here are a user virtual, created a la standard way on /etc/passwd:

    virtual:x:15000:15000:virtual user for nss_map:/dev/null:/sbin/nologin

Then edit the /etc/nssmap.conf

    virtual:x:15000:15000:virtual user for nss_map:/home/virtual:/bin/bash

Note that the user directory is really a base dir in nssmap, each new user can search their home in /home/virtual/logname, where logname is the name used by user to login, and the /home/virtual is the prefix setted in nssmap.conf.

As usual, you can get any of my projects from


Distributed tools

For last months I needed to maintain a number of heterogeneous servers for mi work, I need to do some usually actions, like update a config file, restart a service, create local users etc.

For this purposes there are a lot of applications, like dsh (or full csm), pysh, shmux and many others (only need to perform a search in google using phrase “distributed shell”). Unfortunately for me, I want a easy-to-parse solution, because I’ve a big (really big) number of servers, and I want a single cut-based/awk parsing, and also I need to do some actions as other users (like root, for example) via sudo. Althought many of the existants solutions offers me a subset of this features, I cannot found a complete solution. So I decided to create one 😀

You can find the code, and some packages in the dtools development site. I was use this solution in production environment from months with excelent results, and you can feel free to use.

Of course, its free (of freedom) software, distributed under MIT license.

Enjoy and remember: feedback are welcome 😉

bash ini parser

In some situations i like to use INI files as configuration files, as python do. But bash do not provide a parser for these files, obviously you can use a awk code or a couple of sed calls, but if you are bash-priest and do not want to use nothing more, then you can try the following obscure code:

Update:Added support spaces between keys and values, described in comment #364

Update:Added a writer function, described in comment #370 with examples.

Update:Fix bug when values or keys contains a ‘#’ sign, as described in comment #397. Now only comments at the beginning of line are allowed.

Update:Fix bug in section evaluation when a file which match section expression exists in cwd, as described in comment #436. Fixed also a bug related with
parser when brackets are escaped (read #437.

cfg_parser ()
	ini="$(<$1)"                # read the file
	ini="${ini//[/\[}"          # escape [
	ini="${ini//]/\]}"          # escape ]
	IFS=$'\n' && ini=( ${ini} ) # convert to line-array
	ini=( ${ini[*]//;*/} )      # remove comments with ;
	ini=( ${ini[*]/\	=/=} )  # remove tabs before =
	ini=( ${ini[*]/=\	/=} )   # remove tabs be =
	ini=( ${ini[*]/\ =\ /=} )   # remove anything with a space around =
	ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix
	ini=( ${ini[*]/%\\]/ \(} )    # convert text2function (1)
	ini=( ${ini[*]/=/=\( } )    # convert item to array
	ini=( ${ini[*]/%/ \)} )     # close array parenthesis
	ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick
	ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
	ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
	ini[0]="" # remove first element
	ini[${#ini[*]} + 1]='}'    # add the last brace
	eval "$(echo "${ini[*]}")" # eval the result

cfg_writer ()
    IFS=' '$'\n'
    fun="$(declare -F)"
    fun="${fun//declare -f/}"
    for f in $fun; do
        [ "${f#cfg.section}" == "${f}" ] && continue
        item="$(declare -f ${f})"
        eval $f
        echo "[${f#cfg.section.}]"
        for var in $vars; do
            echo $var=\"${!var}\"

And then you can parse your ini files as following:

# parse the config file called 'myfile.ini', with the following
# contents::
#   [sec2]
#   var2='something'
cfg.parser 'myfile.ini'

# enable section called 'sec2' (in the file [sec2]) for reading

# read the content of the variable called 'var2' (in the file
# var2=XXX). If your var2 is an array, then you can use
# ${var[index]}
echo "$var2"

Unfortunately, the cfg.parser() function do no support embedded spaces
in section names… yet

bashdoc: just another documentation tool

bashdoc is a small utility to make documentation automatically from bash scripts, using awk to frontend parser (and you can add your own frontends in awk language), and reStructuredText as backend parser. bashdoc parse the object script (using awk) and create an intermediate documentation in RST, which is parsed in next step using RST backend.

The fronted allows you to parse more complicated scripts (or other than bash scripts) and the backend allows you to make the output in different formats.

You can download the source code from launchpad project page or using bzr version control system:

$ bzr get lp:bashdoc


comida is a bash script designed to create a FTP (or HTTP, or rsync or…) mirror and maintain the archive synchronized with the source. I design this tool when I was working at the Free Software Office (OSL) in the University of A Corunna, and decided to create a new mirror in Spain which host a lot of free software projects. But, we wanted a single tool to manage all mirrors in the archive, with full integration in our web page (yes, we wanted on-the-fly status page).

You can download the source code from launchpad project page or using bzr version control system:

$ bzr get lp:comida

ssh-keysend: a tool to distribute ssh keys

Update: This project is deprecated by dtools project.

ssh-keysend is a tiny script written in bash which read a number of ssh public keys from a file (according to search pattern) and send these keys to remote hosts (taken from another file, also filtered by specified pattern). The remote host add these keys into authorized_keys file for specified user. Here are an example of use:

$ ssh-keysend [email protected] 10.1.10.*

This example send the key for user [email protected] and send the key to any known_host which match with the pattern 10.1.10.* (yes, it’s a regexp). The key is taken from *.pub files in ~/.ssh/ directory.

You can get the code from launchpad ssh-keysend project page, or get the repository code with bzr:

$ bzr get lp:ssh-keysend