Groesbeek, view of the 'National Liberation Museum 1944-1945' in Groesbeek. © Ton Kersten
Fork me on GitHub
Posts tagged as code

CDE is Open Source

2012-08-06 (125) by Ton Kersten, tagged as code, linux, news

Today the classic, and old, Common Desktop Environment (a.k.a. CDE) was released into the Open Source world.

You can get the very alpha version at SourceForge.

I haven't been able to get a running version by now, but I keep trying.

Good job, guys.

git status in the prompt

2012-07-23 (124) by Ton Kersten, tagged as code, git, linux, sysadm

Working with git a lot I decided I needed some git status in my prompt.

I searched the web and some solutions where almost what I wanted and this one by Sebastian Celis came very close.

But it didn't work with my version of zsh, because that didn't seem to understand the =~ operator.

I also think Sebastian makes things over complicated and so I changed some things aroud.

This is what I came up with:

First make sure this code is included in your ~/.zshenv file

prompt_git_info()
{
    unset __GIT_BRANCH
    unset __GIT_BRANCH_STATUS
    unset __GIT_BRANCH_DIRTY

    local st="$(git status 2>/dev/null)"
    if [[ -n "$st" ]]; then
        local -a arr
        arr=(${(f)st})

        if [[ $arr[1] = *Not\ currently\ on\ any\ branch.* ]]
        then
            __GIT_BRANCH='no-branch'
        else
            __GIT_BRANCH="${arr[1][(w)4]}"
        fi

        if [[ $arr[2] = *Your\ branch\ is* ]]
        then
            if [[ $arr[2] = *ahead* ]]
            then
                __GIT_BRANCH_STATUS='ahead'
            elif [[ $arr[2] = *diverged* ]]
            then
                __GIT_BRANCH_STATUS='diverged'
            else
                __GIT_BRANCH_STATUS='behind'
            fi
        fi

        if [[ $st = *nothing\ to\ commit* ]]
        then
            __GIT_BRANCH_DIRTY='0'
        else
            __GIT_BRANCH_DIRTY='1'
        fi
    fi

    if [[ -n "$__GIT_BRANCH" ]]
    then
        local s="("
        s+="$__GIT_BRANCH"
        case "$__GIT_BRANCH_STATUS"
        in
            ahead)      s+="↑"  ;;
            diverged)   s+="↕"  ;;
            behind)     s+="↓"  ;;
        esac
        if [[ "$__GIT_BRANCH_DIRTY" = "1" ]]
        then
            s+="⚡"
        fi
        s+=")"

        printf " %s%s" "%{${fg[yellow]}%}" $s
    fi
}

and set your prompt to something like this

PS1=$'$C_CYAN%n@%m$(prompt_git_info) $C_WHITE%2~$ $C_OFF'

When I now switch to a directory that is under control of git I get gt status messages in my prompt, like

tonk@mach (master) ~/dir$ git commit -a
[master fca5ac3] Nice, new stuff.
 6 files changed, 88 insertions(+), 12 deletions(-)
tonk@mach (master) ~/.dir$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
tonk@mach (master) ~/.dir$

New version of We-Blog

2012-07-10 (122) by Ton Kersten, tagged as blog, code

Today I released version 0.8 of We-Blog.

I created a Google project and a Google discussion group.

Version 0.8 is now the stable branch and 0.9 the development branch.

What's new?

Well, to be really honest, not that much. I fixed some minor bugs and did a lot of code cleanup. Although the original code of Jaromir was very nice, there was some room for improvement. I removed a lot of double functions and variables and put them all together in a We.pm Perl module. Saves a lot of work with an update.

Finding key codes on Linux

2012-07-04 (121) by Ton Kersten, tagged as code, linux, sysadm

It often happens that I get into a situation where I need to know key codes of pressed keys. On my Mac that's simple. Just use the Key Codes by Many Tricks.

But on Linux I constantly was trying to find out which key produced what.

So I ended up writing a program for that. I started of in the shell, but that ended up being rather tricky and unnecessary complicated. So I redid the whole thing in C.

This is the result

/*
 * Program     : code.c
 * Author      : Ton Kersten
 */

#include <stdio.h>
#include <curses.h>

#define DONE    'q'
#define ESC     0x1b
#define SPC     0x20

char ch;

main()
{
    printf("Press '%c' to quit!\n\n", DONE);

    /*
     * Put the terminal in raw mode, with no echo
     */
    system("stty raw -echo");

    /*
     * Print the header
     */
    printf("%4s\t%4s\t%4s\t%4s\r\n", "Char", " Hex", " Oct", " Dec");
    printf("%4s\t%4s\t%4s\t%4s\r\n", "----", "----", "----", "----");

    /*
     * Set the initial loop value to something odd
     */
    ch = DONE-1;
    while ( ch != DONE )
    {   ch = getchar();

        /*
         * Character read. Display it. Look out for < 0x20
         */
        if ( ch < SPC )
        {   if ( ch == ESC )
            {   /*
                 * Esc. Just say 'Esc'
                 */
                printf("%-4s\t0x%02x\t%04o\t%04d\r\n",
                        "Esc", ch, ch, ch);
            }
            else
            {   /*
                 * < ' '. Print Control character
                 */
                printf("^%-c\t0x%02x\t%04o\t%04d\r\n",
                        ch-1+'A', ch, ch, ch);
            }
        }
        else
        {   /*
             * Normal character. Display it normally
             */
            printf("%-4c\t0x%02x\t%04o\t%04d\r\n",
                        ch, ch, ch, ch);
        }
    }

    /*
     * Put the terminal back to something usefull
     */
    system("stty sane echo");
}

And this is an example of the output

Press 'q' to quit!

Char     Hex     Oct     Dec
----    ----    ----    ----
Esc     0x1b    0033    0027
O       0x4f    0117    0079
P       0x50    0120    0080
Esc     0x1b    0033    0027
[       0x5b    0133    0091
2       0x32    0062    0050
4       0x34    0064    0052
~       0x7e    0176    0126
q       0x71    0161    0113

Shell tip

2012-07-04 (120) by Ton Kersten, tagged as code, linux, sysadm

During one of my teaching sessions a student asked me if it was possible to find the number of spaces in a variable.

As with all questions in Linux and UNIX the answer is a simple

Of course that's possible. In UNIX and Linux everything is possible.

With some sed or awk this can be done within seconds. But I wanted it done completely within the shell, in this case bash.

This is what I came up with

P="John and Paul and Ringo and George where the Beatles"
R=${P//[! ]/}       # Remove everything that is NOT a space
echo ${#R}          # Show the number of characters (spaces) that are left

And this also works in the Korn shell (ksh) and the Z-shell (zsh).

New header

2012-06-28 (117) by Ton Kersten, tagged as code, linux

Today I've posted a new version of the header program.

Nothing really fancy happened, just added support for zonefiles, in this case the Bind ones.

It's available at the usual places.

sed tips and tricks

2012-06-22 (116) by Ton Kersten, tagged as code, linux, sysadm

I'm creating a Puppet Starter Kit with some standard manifests included and a complete set of documentation. All documentation should be written in Markdown and will be served by Markdoc. But I want to generate all Markdown files from the Puppet manifests, so I only need to document the manifest file. Generating the Markdown is not that difficult, except that I kept ending up with empty lines at the top of the manifest code and I wanted to get rid of those. Of course this should be done with sed, because the whole generation process is written in bash. When playing around with sed I found

sed '/./,$!d' filename

which, I think, is genius in it's simplicity. After you find something, do not remove. Life in UNIX and Linux is nice!

Read more »

Puppet updates

2012-06-18 (115) by Ton Kersten, tagged as code, puppet, sysadm

When working with Puppet and a VCS (like git and SVN) it's nice to have a simple way of updating the Puppet tree.

My tree is always in /etc/puppet and owned by user and group puppet. User puppet is allowed to checkout the complete tree from git or subversion.

I have created two one-liners to update the complete tree and make sure all rights are still correct.

update_svn

#!/bin/bash
# update_svn
su - puppet -c 'cd /etc/puppet; svn up; cd doc; ../bin/gendoc'

update_git

#!/bin/bash
# update_git
su - puppet -c 'cd /etc/puppet; git pull; cd doc; ../bin/gendoc'

But, of course, it's not handy to type update_git today and update_svn tomorrow. And I also don't want a path to /etc/puppet/bin.

The solution is a very simple one, as always:

cd /usr/local/bin
ln -s /etc/puppet/bin/update_git pupdate

and now I only have to type pupdate and things work out.

Eeepc battery script for 2.6.24 AND 2.6.25

2008-09-13 (1) by Ton Kersten, tagged as code

The new kernel for the EeePC (2.6.25) has deprecated the /proc/acpi/battery interface, so I had to write a new script for use in my own zsh prompt.

The script will work in both 2.6.24 and 2.6.25, so without further ado, here it is. It is written as a function for easy inclusion in any prompts.

#!/bin/zsh
bat() {
    PROC=/proc/acpi/battery/BAT0
    SYS=/sys/class/power_supply/BAT0/uevent
    STATE=
    # dc: design capacity, rc: remaining capacity
    if [ -f $PROC/info ]
    then
        STATE=$PROC/state   # 2.6.24
        dc=$(grep 'last full' < $PROC/info | awk '{ print $4 }')
        rc=$(grep 'remaining' < $PROC/state | awk '{ print $3 }')
    elif [ -f $SYS ]
    then
        STATE=$SYS          # 2.6.25
        dc=$(grep '\<power_SUPPLY_CHARGE_FULL\>' < $SYS | awk -F= '{ print $2 }')
        rc=$(grep '\<power_SUPPLY_CHARGE_NOW\>' < $SYS | awk -F= '{ print $2 } ')
    else
        exit
    fi
    p=$(echo 3k $rc $dc / 100 \* p | dc )

    if grep -iq discharging $STATE
    then
        printf " %02d" "$p"
    else
        if [ ${p%.*} -lt 100 ]; then
        printf " %02d+" "$p"
        fi
    fi
}
bat

Update

After some tweaking I even made a better one which saves a few greps.

#!/bin/zsh
bat() {
    PROC=/proc/acpi/battery/BAT0
    SYS=/sys/class/power_supply/BAT0/uevent
    STATE=
    # dc: design capacity, rc: remaining capacity
    if [ -f $PROC/info ]
    then
        STATE=$PROC/state   # 2.6.24
        dc=$(awk '/last full/ { print $4 }' $PROC/info)
        rc=$(awk '/remaining/ { print $3 }' $PROC/state)
    elif [ -f $SYS ]
    then
        STATE=$SYS          # 2.6.25
        dc=$(awk -F= '$1 ~ /^POWER_SUPPLY_CHARGE_FULL$/ { print $2 }' $SYS)
        rc=$(awk -F= '$1 ~ /^POWER_SUPPLY_CHARGE_NOW$/  { print $2 }' $SYS)
    else
        return 0
    fi

    p=$(echo 3k $rc $dc / 100 \* p | dc )

    if grep -iq discharging $STATE; then
        printf " %02d" "$p"
    else
        if [ ${p%.*} -lt 100 ]; then
        printf " %02d+" "$p"
        fi
    fi
}
bat

Update 2

Just found that there is also a nice tool, called acpi...which makes it even more easy:

% acpi -V
Battery 0: Full, 100%
AC Adapter 0: on-line
Thermal 0: ok, 53.0 degrees C
Cooling 0: Processor 0 of 7