TurnKey Linux Virtual Appliance Library

Smack yourself if you don't use generic shell script hooks

Smack yourself in the forehead if you don't use the following snippet (or an equivalent) in all custom shell scripts that could benefit from a hooking mechanism:


run_scripts()
{
    for script in $1/*; do

        # skip non-executable snippets
        [ -x "$script" ] || continue

        # execute $script in the context of the current shell
        . $script
    done
}

run_scripts path/to/hooks.d

I've found this pattern useful in nearly every sufficiently complex shell script I maintain, and I even use it to help manage my bashrc and xsession configurations:


$ ls .bashrc.d/
paths git editor pager autologout qemu tmpdirs scratch

$ ls .xsession.d/
10-lang 10-tmpdir 90-bell 90-kbdrate 91-xscreensaver 99-fvwm-conf

Features:

  1. Modular: add or remove code without having to edit a big monolithic file.

  2. Order of execution is determined by the filename. Changing the order is as simple as changing a number prefix.

  3. Disable execution by removing execution bit:

    		chmod -x .bashrc.d/git
    

These days breaking down configurations into separate modular files like this is common in the Linux world, so by now I expect many experienced users are wondering why I'm channeling Captain Obvious. Just keep in mind that many Linux newbies haven't yet learned all our best practices and some lessons are worth reteaching.

Why not share your own tricks? Post a comment!

You can get future posts delivered by email or good old-fashioned RSS.
TurnKey also has a presence on Google+, Twitter and Facebook.

Comments

Care to share your functions in .bashrc.d/ ?

They look interesting:

paths CDPATHs?

git see [1] for mine

editor export EDITOR=vi

pager emport PAGER=less

autologout ??

qemu ??

tmpdirs ??

scratch ??

[1] My git functions:

function gvc { git commit -m "$*" }

function gam { git commit -am "$*" }

Liraz Siri's picture

My shell cruft

Hi Ed! Scratch is where I put random shell functions or variables I write on-the-fly for the task at hand (e.g., a test case I don't want to retype over and over again).

It's all kind of boring and specific to my workload which is why I didn't share, but since you asked...

$ cat autologout
# logout from the console if no activity in 300 seconds
if [ -z "$DISPLAY" ]; then
    TMOUT=300
fi

$ cat qemu
QEMU_OPTIONS="-m 256"

# vde switch to connect to
QEMU_VDE=tap-bridged

# anything you put here is used as the seed for choosing the mac address
QEMU_MACADDR=""

# examples: kvm qemu qemu-x86_64
QEMU_BIN=kvm

function qemu() {
    if [ -n "$QEMU_VDE" ]; then
        sock=/var/run/vde.$QEMU_VDE
        if [ ! -d $sock ]; then
            echo "error: no such VDE interface ($QEMU_VDE)"
            return 1
        fi
        nohup vdeq $QEMU_BIN \
            -net vde,sock=$sock \
            -net nic,macaddr=$(qmacaddr $QEMU_MACADDR) \
            $QEMU_OPTIONS \
            $@
    else
        nohup $QEMU_BIN $QEMU_OPTIONS $@
    fi

}

$ cat git
export GIT_AUTHOR_NAME="Liraz Siri"
export GIT_AUTHOR_EMAIL="liraz@sterilesecurity.com"
export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL

git_branch_bin=$(which git-branch 2>/dev/null)
function git-branch()
{
    local delete=no
    for arg; do
        [ "$arg" == "-D" ] && delete=yes
    done
    if [ "$delete" == "yes" ]; then
        $git_branch_bin -v $*
    else
        $git_branch_bin -v -a $*
    fi
}

Oh and sorry for the late reply. I've been offline for most of these last two weeks. Too bad you didn't create an account because then you would get email notification on reply. I find that very useful myself in keeping track of the discussion (especially when it's late!).

I think Shell scripts allow

I think Shell scripts allow several commands that would be entered manually at a command line interface to be executed automatically, and without having to wait for a user to trigger each stage of the sequence. For example, in a directory with three C source code files, rather than manually running the four commands required to build the final program from them, one could instead create a C shell script, here named build and kept in the directory with them, which would compile them automatically.

curt

CA


I am smacking my forehead

I am smacking my forehead now. Good work on this. Also, glad you defined "Scratch."

I had trouble adding extra

I had trouble adding extra hooks while configuring Ssh session. I was trying to add extra stuff to alter the environment but they conflicted with some libraries and functions. I stumbled across your post recently and I am now trying to add generic hooks. So far it worked well. I changed the order and it so damn easy! Removing codes without the need to go through the whole of it and altering here and there. It is such a big blessing.

Shortcut

run-parts util, it's installed by default in all majors distributions.

run-parts -a "$@" -- DIR

-a    pass all parameters to script
--     end for parameters
DIR directory with all hooks scripts
 

run-parts

run-parts won't run the scripts in your current shell environment and so can't be used to alter that environment. 

hooks

i know this thread is quite old, but i wanted to mention.. i took this a bit further and created ${HOME}/.rc.d. in there, i have FXX-name and AXX-name, F for functions, A for aliases. loads very nicely =)

Liraz Siri's picture

What's the rational for separating functions and aliases?

Hi Kevin, thanks for sharing. I never thought to separate shell hooks by function/alias. What's your rational for doing that?

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <p> <span> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <strike> <caption>

More information about formatting options

Leave this field empty. It's part of a security mechanism.
(Dear spammers: moderators are notified of all new posts. Spam is deleted immediately)