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

Installing Pandoc

2013-01-26 (132) by Ton Kersten, tagged as linux, pandoc

John Macfarlane released a new version of Pandoc that has a lot of new enhancements. A lot of things have changed in the Markdown input types and it’s now compatible with PHP Markdown. This is very nice, because a lot of implementations use the extensions defined by PHP Markdown.

I downloaded the dmg file to install it on my MacBook Pro and it works like a charm.

So, I decided to install it on my new CentOS 6 server to build documents there. Well, I was in for a nice surprise.

After cloning the source from github I started as documented in the INSTALL file

make prep

and now I get

Resolving dependencies...
cabal: cannot configure directory-1.1.0.0. It requires old-time ==1.0.*
For the dependency on old-time ==1.0.* there are these packages:
old-time-1.0.0.0, old-time-1.0.0.2, old-time-1.0.0.3, old-time-1.0.0.4,
old-time-1.0.0.5, old-time-1.0.0.6 and old-time-1.0.0.7.
However none of them are available.
old-time-1.0.0.0 was excluded because pandoc-1.10.0.5 requires old-time ==1.1.*
old-time-1.0.0.7 was excluded because pandoc-1.10.0.5 requires old-time ==1.1.*

etc.

I kept tweaking the makefile and tried almost everything possible, but I was caught in a cyclic dependency loop. So, time to rethink and use Google.

I had already figured out it had to do with a cabal and ghc version that are to old, so it’s time to update.

I found newer Cabal versions at JustHub.

I started removing every RPM with haskel or ghc in the name and removed ~/.cabal and ~/.ghc directories to start of fresh. Then:

sudo rpm -Uhv
http://sherkin.justhub.org/el6/RPMS/x86_64/justhub-release-2.0-4.0.el6.x86_64.rpm
export PATH=/usr/hs/bin:~/.cabal/bin:$PATH
cabal install cabal-dev
cd ~/pandoc
make prep
.
.

Now it compiles but it breaks with:

make install
cabal-0.14.0: Error: some packages failed to install:
pandoc-1.10.0.5 failed during the tests phase. The exception was:
ExitFailure 1
cabal --config-file=/home/tonk/qq/pandoc/cabal-dev/cabal.config:
/usr/hs/tools/cabal-0.14.0 failure (return code=1)
make: *** [install] Error 1

Some tests fail, but I just removed --enable-tests from the Makefile and I got a working executable. Simply copy it to the ~/.cabal/bin directory, install the man-page and everything is fine.

I think it should be simpler, but for now I’m a happy camper.

rsync on a not standard port

2013-01-21 (131) by Ton Kersten, tagged as linux, sysadm

Today a colleague asked me to sync some files to a server that is not listening on SSH port 22.

I normally create a configuration entry in my ~/.ssh/config file, like

Host tosync
    Hostname syncer.example.com
    Port 1234
    User syncuser

and then command

rsync -va --progress --inplace . tosync:

But this time I didn't want to create the entry in my SSH configuration, because I need this trick in a script. So I started to read the rsync manpage and after some experimenting I found

rsync -va --progress --inplace --rsh='ssh -p1234' . syncuser@syncer.example.com:

This syncs the current directory to host syncer.example.com on port 1234 as user syncuser.

MySQL backup error

2012-08-09 (126) by Ton Kersten, tagged as linux, mysql

After upgrading my MySQL database server from version 5.0.95 to 5.1.61 I suddenly got these errors in the backup logging.

mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `EVENTS`': Cannot
proceed because system tables used by Event Scheduler were found damaged at server start
(1577)
dbdump gave errorcode 2 for database 'information_schema'
2012-08-09 09:07:53 -> Finished MySQL backup on host 'xxx.tonkersten.com'

Hmm, no idea what has happened. I hope I didn't do something stupid.

Asking Google I found out that the information_schema tables where changed during the upgrade and that I could recreate the error with:

mysql> use information_schema
Database changed

mysql> SELECT /*!40001 SQL_NO_CACHE */ * FROM EVENTS;
ERROR 1577 (HY000): Cannot proceed because system tables used by Event Scheduler were found damaged at server start
mysql> Bye

So I tried to repair the error with:

mysql_upgrade -u root -h localhost -p --verbose

but still the same error.

Turns out that the MySQL server needs to be restarted for this to work.

Now I get

mysql> use information_schema
Database changed

mysql> SELECT /*!40001 SQL_NO_CACHE */ * FROM EVENTS;
Empty set (0.00 sec)
mysql> Bye

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$

No network on CentOS 6

2012-07-17 (123) by Ton Kersten, tagged as linux, sysadm

When installing a minimal CentOS 6 system, minimal really, really means minimal. After a reboot the network interfaces do not start, so network connectivity is non existing.

Looking into that I noticed that the file /etc/sysconfig/network-scripts/ifcfg-eth0 contained

DEVICE=eth0
HWADDR=11:22:33:44:55:66
NM_CONTROLLED=yes
ONBOOT=no
BOOTPROTO=dhcp
TYPE=Ethernet
USERCTL=no
PEERDNS=yes
IPV6INIT=no

The lines that mess things up are NM_CONTROLLED=yes meaning the interfaces are managed with NetworkManager, which isn’t actually installed as part of a minimal install. You want a minimal install, you get a minimal install. And ONBOOT=no, meaning "do not start the interface on boot". How stupid is that!

The trick is to run something like system-config-network-tui to set the IP addresses manually, but as you might imagine, that's not installed either.

So you best edit /etc/sysconfig/network-scripts/ifcfg-eth0 by hand and set it to:

DEVICE=eth0
HWADDR=11:22:33:44:55:66
NM_CONTROLLED=no
ONBOOT=yes
BOOTPROTO=none
TYPE=Ethernet
USERCTL=no
PEERDNS=yes
IPV6INIT=no
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=192.168.0.254

The USERCTL=... line is optional: If set to yes it lets non-root users control the interface.

After setting this a service network restart will do the trick.

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 »