<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Unix hacker and programmer sharing things he finds useful.</description><title>dpc</title><generator>Tumblr (3.0; @dpcucoreinfo)</generator><link>http://dpc.ucore.info/</link><item><title>Asynchronous GNU Readline printing</title><description>&lt;p&gt;Some while ago I&amp;#8217;ve spend my time developing a &lt;a href="http://github.com/dpc/xmppconsole"&gt;XMPP command line client&lt;/a&gt; which is using &lt;a href="http://code.stanziq.com/strophe/"&gt;strophe XMPP library&lt;/a&gt; to handle XMPP and &lt;a href="http://tiswww.case.edu/php/chet/readline/rltop.html"&gt;GNU Readline&lt;/a&gt; for I/O.&lt;/p&gt;

&lt;p&gt;The idea was to have a readline prompt at the bottom and yet be able to asynchronously print incoming messages above it - in the &amp;#8220;log window&amp;#8221;.&lt;/p&gt;

&lt;p&gt;It seems that many people were looking for solution already:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/1512028/gnu-readline-how-do-clear-the-input-line"&gt;GNU Readline: how do clear the input line?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/691652/using-gnu-readline-how-can-i-add-ncurses-in-the-same-program"&gt;Using GNU Readline; how can I add ncurses in the same program?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I haven&amp;#8217;t found any satisfying answer on the web so I&amp;#8217;d like to present my own solution.&lt;/p&gt;

&lt;p&gt;Basic idea is to use alternate (asynchronous) GNU Readline interface and on each new asynchronous print:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;save a copy of current line state&lt;/li&gt;
&lt;li&gt;clear both prompt and current line (content + position)&lt;/li&gt;
&lt;li&gt;force screen update&lt;/li&gt;
&lt;li&gt;print asynchronous event (followed by a newline)&lt;/li&gt;
&lt;li&gt;restore prompt and current line state&lt;/li&gt;
&lt;li&gt;force screen update&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Simple it is, indeed and you can see &lt;a href="http://github.com/dpc/xmppconsole/blob/master/src/io.c"&gt;a working code&lt;/a&gt; if you don&amp;#8217;t belive.&lt;/p&gt;

&lt;p&gt;The only thing that I was unable to get is preventing putting the original confirmed readline buffer in &amp;#8220;log window&amp;#8221;. As this is not a big deal for my requirements the complete and universal solution would be able to change what the user typed in the readline buffer just before it&amp;#8217;s getting scrolled up and becoming part of the &amp;#8220;log window&amp;#8221;.&lt;/p&gt;

&lt;p&gt;I hope someone will fine it useful, like I do.&lt;/p&gt;</description><link>http://dpc.ucore.info/post/16062560132</link><guid>http://dpc.ucore.info/post/16062560132</guid><pubDate>Wed, 18 Jan 2012 16:03:00 +0100</pubDate><category>c</category><category>programming</category><category>readline</category><category>xmpp</category></item><item><title>Teach your shell how to grab you attention</title><description>&lt;p&gt;In my daily work it&amp;#8217;s often a case when I have long-running process that I have to wait for to complete and I don&amp;#8217;t want to stare at the shell all the time.&lt;/p&gt;

&lt;p&gt;To do what I want I&amp;#8217;ve created two commands. First is &lt;code&gt;tick&lt;/code&gt; that I store under &lt;code&gt;$HOME/bin/tick&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh

if which mplayer 1&amp;gt;/dev/null ; then
    mplayer -quiet -nolirc "$HOME/usr/sounds/tick.ogg" 1&amp;gt;/dev/null 2&amp;gt;/dev/null &amp;amp;
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I use it during daily work, and in some of my scripts to play simple, short &amp;#8220;tick&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Second is &lt;code&gt;notify&lt;/code&gt;, which is a bit more extensive notification command. The content of &lt;code&gt;$HOME/bin/notify&lt;/code&gt; is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh

if which mplayer 1&amp;gt;/dev/null; then
    mplayer -quiet -nolirc "$HOME/usr/sounds/alarm.ogg" 1&amp;gt;/dev/null 2&amp;gt;/dev/null &amp;amp;
fi

if which notify-send 1&amp;gt;/dev/null ; then
        notify-send -t 3000 --hint=int:transient:1 -- "$1" "$2"
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not only it plays longer and louder alarm sound, but additionally it uses &lt;code&gt;notify-send&lt;/code&gt; to display notification on your desktop so you know exactly what happened.&lt;/p&gt;

&lt;h3&gt;Integrate &lt;code&gt;tick&lt;/code&gt; and &lt;code&gt;notify&lt;/code&gt; into ZSH&lt;/h3&gt;

&lt;p&gt;In a depth of my complex ZSH configuration I do something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function preexec {
    export ZSH_CMD_TICK_TS=`date '+%s'`
    export ZSH_CMD_TICK_CMD="$1"
}

function precmd {
    line-tick
}

export ZSH_CMD_TICK_TS=`date '+%s'`
function line-tick() {
    TS=`date '+%s'`

    if [ $(($ZSH_CMD_TICK_TS + 60)) -lt $TS ]; then
        notify "Cmd finished: $ZSH_CMD_TICK_CMD"
    elif [ $(($ZSH_CMD_TICK_TS + 10)) -lt $TS ]; then
        tick
    fi
    export ZSH_CMD_TICK_TS=$TS
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So what does it do? First, before execution of every command &lt;code&gt;preexec&lt;/code&gt; will record current timestamp and command that is about to be executed. Then, after command has finished, but before the new prompt is displayed &lt;code&gt;precmd&lt;/code&gt; will call &lt;code&gt;line-tick&lt;/code&gt; to check what should be done. &lt;code&gt;line-tick&lt;/code&gt; will compare the current timestamp with the one recorded by &lt;code&gt;preexec&lt;/code&gt;. If the time spent on execution of the command is longer than 60 seconds, &lt;code&gt;notify&lt;/code&gt; command will be triggered to tell us what command has finished and play alarm sound. If the command execution time was smaller, but still longer than 10 seconds &lt;code&gt;tick&lt;/code&gt; will be used instead.&lt;/p&gt;</description><link>http://dpc.ucore.info/post/16059548635</link><guid>http://dpc.ucore.info/post/16059548635</guid><pubDate>Wed, 18 Jan 2012 13:56:00 +0100</pubDate><category>zsh</category><category>shell</category><category>notification</category></item><item><title>Add some structure to your home directory.</title><description>&lt;p&gt;Personally I find it very useful to keep the same structure on every Unix account I&amp;#8217;m using. This is somehow connected with the &lt;a href="/post/15579697737/keep-you-dot-files-in-sync/"&gt;idea of keeping dot-files in sync&lt;/a&gt; between all of them.&lt;/p&gt;

&lt;p&gt;I loosely base the structure on Unix root filesystem structure:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;code&gt;~/bin&lt;/code&gt; - my handy scripts&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/doc&lt;/code&gt; - documents of any kind&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/etc&lt;/code&gt; - files keeping settings of &lt;code&gt;~/bin&lt;/code&gt; scripts&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/lab&lt;/code&gt; - where I do my programming tasks&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/tmp&lt;/code&gt; - temporary files, downloads&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/opt&lt;/code&gt; - account-local software&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;More on &lt;code&gt;~/opt&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;It&amp;#8217;s often a case that one has to use custom software on non-root account. In such cases I just download the software source to &lt;code&gt;~/opt/src&lt;/code&gt;, extract it, go to extracted dir and do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./configure.sh --prefix="$HOME/opt"
make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or similar procedure, depending on the software building system.&lt;/p&gt;

&lt;p&gt;For this to fully and seamlessly work, on have to modify some system paths. Using &lt;a href="/post/15231363127/prepend-or-append-to-path-like-environment-variable"&gt;&lt;code&gt;append_env&lt;/code&gt; function&lt;/a&gt; I&amp;#8217;m doing something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;prepend_env PATH "$HOME/bin:$HOME/opt/bin:$HOME/opt/usr/bin"
prepend_env LD_LIBRARY_PATH "$HOME/opt/lib"
prepend_env LD_RUN_PATH "$HOME/opt/lib"
prepend_env PKG_CONFIG_PATH "$HOME/opt/lib/pkgconfig"
prepend_env LIBRARY_PATH "$HOME/opt/lib"
prepend_env C_INCLUDE_PATH "$HOME/opt/include"

[ -z "$MANPATH" ] &amp;amp;&amp;amp; export MANPATH="`manpath`"
prepend_env MANPATH "$HOME/opt/share/man"
&lt;/code&gt;&lt;/pre&gt;</description><link>http://dpc.ucore.info/post/15611094943</link><guid>http://dpc.ucore.info/post/15611094943</guid><pubDate>Tue, 10 Jan 2012 08:00:00 +0100</pubDate></item><item><title>Keep you dot-files in sync.</title><description>&lt;p&gt;To work efficiently it&amp;#8217;s necessary to customize and personalize a lot. After some time one gets used to his customizations and start to depend on them. For example: I map Caps Lock to Escape, as I tend to use vi-mode in any software that supports it and I find Caps Lock key useless anyway. After years of doing so, I simple can not work if Caps Lock is not mapped to Escape. That&amp;#8217;s why it&amp;#8217;s important for me to be able to easily import my settings to any account I am given: on my personal computer, remote shell, or temporary account.&lt;/p&gt;

&lt;p&gt;For this I use git. Generally, using git for revisioning dot-files is not recommended, but in practice it works really well. For every Unix account I am to use, first thing I am doing is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd
git init .
git remote add origin &amp;lt;path-to-my-home-skeleton-repository&amp;gt;
git fetch
git checkout master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I log out, and then log in, and I&amp;#8217;m able to work the way I&amp;#8217;m used to.&lt;/p&gt;

&lt;p&gt;On every computer, there might be reason for local customization. That&amp;#8217;s why I revision only a common settings, and often include local-only settings.&lt;/p&gt;

&lt;p&gt;E.g. in my .zshrc I use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[ -f "$HOME/.zshrc.local" ] &amp;amp;&amp;amp; source "$HOME/.zshrc.local"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this approach, I can have things specific for particular machine/account in a file, that I don&amp;#8217;t put under revision control.&lt;/p&gt;</description><link>http://dpc.ucore.info/post/15579697737</link><guid>http://dpc.ucore.info/post/15579697737</guid><pubDate>Mon, 09 Jan 2012 21:53:00 +0100</pubDate><category>home</category><category>git</category></item><item><title>Prepend or append to PATH like environment variable.</title><description>&lt;p&gt;In Unix there are quite a lot variables representing path lists of different kind similar to &lt;code&gt;PATH&lt;/code&gt; like &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;, &lt;code&gt;PKG_CONFIG_PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Usual idiom to modify these variables is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$PATH="$PATH:/new/path/to/something"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I found it quite a lot of typing in a daily work, so I&amp;#8217;m using functions shortening the above to just:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;append_env PATH /new/path/to/something
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The version for Bash is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function append_env {
    if [ -z "${!1}" ]; then
        export "$1"="$2"
    else
        export "$1"="${!1}:$2"
    fi
}
function prepend_env {
    if [ -z "${!1}" ]; then
        export "$1"="$2"
    else
        export "$1"="$2:${!1}"
    fi
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And for Zsh:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function append_env {
    eval "local v=\$$1"
    if [ -z "$v" ]; then
        export "$1"="$2"
    else
        export "$1"="$v:$2"
    fi
}
function prepend_env {
    eval "local v=\$$1"
    if [ -z "$v" ]; then
        export "$1"="$2"
    else
        export "$1"="$2:$v"
    fi
}
&lt;/code&gt;&lt;/pre&gt;</description><link>http://dpc.ucore.info/post/15231363127</link><guid>http://dpc.ucore.info/post/15231363127</guid><pubDate>Tue, 03 Jan 2012 08:00:00 +0100</pubDate><category>shell</category></item><item><title>Make tmux and ssh-agent work smoothly.</title><description>&lt;p&gt;A lot of people using remote shell accounts must deal with a problem of stale environment variables  for &lt;code&gt;ssh-agent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At each &lt;code&gt;ssh&lt;/code&gt; connection, new socket is created and variable &lt;code&gt;$SSH_AUTH_SOCK&lt;/code&gt; is set to point to it. The problem is that shells that are already opened can&amp;#8217;t have this environmental variable updated automatically. I&amp;#8217;ve seen a lot of complex solutions to this (writing some update scripts and aliasing &lt;code&gt;ssh&lt;/code&gt; command, etc.).&lt;/p&gt;

&lt;p&gt;Finally I&amp;#8217;ve realized there&amp;#8217;s a simpler solution. Instead of updating &lt;code&gt;$SSH_AUTH_SOCKET&lt;/code&gt;, make it  point at one location only: a symlink, and update that symlink at each connection. Just as usual in Computer Science, the problem is solved by just another level of indirection.&lt;/p&gt;

&lt;p&gt;In my personal scripts I use something much more complex, but the basic idea is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if [ -z "$TMUX" ]; then
    if [ ! -z "$SSH_TTY" ]; then
        if [ ! -z "SSH_AUTH_SOCK" ]; then
            ln -sf "$SSH_AUTH_SOCK" "$HOME/.wrap_auth_sock"
        fi
        export SSH_AUTH_SOCK="$HOME/.wrap_auth_sock"

        exec "$HOME/bin/tmux-session" "sshwrap"
    fi
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;if already running inside &lt;code&gt;tmux&lt;/code&gt;, skip&lt;/li&gt;
&lt;li&gt;if not connected via &lt;code&gt;ssh&lt;/code&gt;, skip&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;$SSH_AUTH_SOCK&lt;/code&gt; is defined, update the symlink&lt;/li&gt;
&lt;li&gt;export one and only correct &lt;code&gt;$SSH_AUTH_SOCK&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;launch tmux&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For completeness, here goes my &lt;code&gt;$HOME/bin/tmux-session&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
# Reattach to (or spawn new if does not exist)
# tmux session "$1"

export STY="tmux-$1"
if tmux has-session -t "$1"; then
    exec tmux attach-session -t "$1"
else
    exec tmux new-session -s "$1"
fi
&lt;/code&gt;&lt;/pre&gt;</description><link>http://dpc.ucore.info/post/14988791712</link><guid>http://dpc.ucore.info/post/14988791712</guid><pubDate>Thu, 29 Dec 2011 23:07:00 +0100</pubDate><category>tmux</category><category>shell</category><category>ssh</category></item></channel></rss>

