Bashful Plumber.

Goal: A script that continuously show date and time, with Dzen2, and Conky.

Before you dip your toe to scripting, you might desire to know the reason by reading this overview.

Reading


Piping and Forking in Many Languages

This article is one part of a collection. All integrated, on related to another. So we can compare each other quickly.

Tutorial/ Guidance/ Article: [ Pipe Overview ] [ BASH ] [ Perl ] [ Python ] [ Ruby ] [ PHP ] [ Lua ] [ Haskell ]

Source Code Directory: [ BASH ] [ Perl ] [ Python ] [ Ruby ] [ PHP ] [ Lua ] [ Haskell ]


A Very Bashful Start

Welcome to n00berland. Begin with simple script. We will use this loop as a source feed to pipe. This step won’t introduce Pipe nor Fork.

This script only show an infinite loop showing local time. Each updated in one second interval. We manage this interval by delaying, using sleep code.

Source:

#!/usr/bin/env bash

# endless loop
while true; do 
    date +'%a %b %d %H:%M:%S'
    sleep 1
done

Call to this simple code would produce time marching, one after another, below the command line prompt.

Pipe: Basic

Similar Code: [ BASH basic ] [ Perl basic ] [ Python basic datetime ] [ Python basic time ] [ Ruby basic ] [ PHP basic ] [ Lua basic ] [ Haskell basic ]


Port to other Language

I respect the reader, that you are smart. You might be wondering, why I have to put this very basic script in this tutorial. This script may looks simple in BASH, and have very similar looks in most popular scripting language. But it would have very different approach in other language. As you can see in an obscure language below, Haskell has no loop, but using forever control.

Source:

import Data.Time.LocalTime
import Data.Time.Format

import Control.Concurrent
import Control.Monad

-- ----- ----- ----- ----- -----
-- wrap Funktion

myTimeFormat = "%a %b %d %H:%M:%S"

wFormatTime :: FormatTime t => t -> String
wFormatTime myUtcTime = formatTime 
  Data.Time.Format.defaultTimeLocale myTimeFormat myUtcTime

wSleep :: Int -> IO ()
wSleep mySecond = threadDelay (1000000 * mySecond)

printDate = do
     now <- getZonedTime
     let nowFmt = wFormatTime now
     putStrLn nowFmt
     wSleep 1

-- ----- ----- ----- ----- -----
-- main

main = forever $ printDate

External Command as Source Feed

Beside previous simple loop that is used as Internal Command, this tutorial also provide Conky as External Command in asset directory. I made it as simple as possible.

Source:

conky.config = {
    out_to_x = false,
    out_to_console = true,
    short_units = true,
    update_interval = 1
}

conky.text = [[\
${time %a %b %d %H:%M:%S}\
]]

A Native Pipe Between External Command

This step is overview of Pipe between two external command. This is a very simple. Only using | character. This very short script is using conky as pipe source feed and less as pipe target. Showing time and date forever in the console.

This infinite pipe run in time-less fashioned.

I had made additional dirname function, relative to the BASH source, to locate the conky script assets.

Source:

#!/usr/bin/env bash

dirname=$(dirname $(readlink -f "$0"))
path="$dirname/../assets"

cmdin="conky -c $path/conky.lua"
cmdout="less" # or dzen2

$cmdin | $cmdout

You can see, how simple it is. This would have less output similar to this below.

Pipe: to Less

Your wallpaper might be different than mine.

Similar Code: [ BASH native ] [ Perl uni IO ] [ Perl uni open ] [ Python subProcess] [ Ruby popen ] [ PHP popen ] [ Lua popen ] [ Haskell createProcess ]


A Native Pipe from Internal Function

Using internal function as source feed to external command is straight forward. This should be self explanatory.

Other language has more complex mechanism for this. Most common is using subProcess or Popen. From this step forward, this would looks different in other language.

Source:

#!/usr/bin/env bash

generated_output() {
    # endless loop
    while :; do 
      date +'%a %b %d %H:%M:%S'
      sleep 1
    done
}

cmdout="less" # or dzen2

generated_output | $cmdout

Similar Code: [ BASH pipe ] [ Perl pipe open ] [ Perl pipe IO ] [ Python subProcess ] [ Ruby pipe IO ] [ Ruby popen ] [ Ruby open3 ] [ Ruby PTY ] [ PHP popen ] [ Lua popen ] [ Haskell createProcess ]


Fork Overview

Fork in bash is also simple. All it takes is jus & character.

This step use internal function as source feed, as continuation of previous step.

This step use dzen2, with complete parameters. This dzen2 is forked, running in the background. Detached from the script, no need to wait for dzen2 to finish the script.

Source:

#!/usr/bin/env bash

generated_output() {
    # endless loop
    while :; do 
      date +'%a %b %d %H:%M:%S'
      sleep 1
    done
}

xpos=0
ypos=0
width=640
height=24
fgcolor="#000000"
bgcolor="#ffffff"
font="-*-fixed-medium-*-*-*-12-*-*-*-*-*-*-*"

parameters="  -x $xpos -y $ypos -w $width -h $height" 
parameters+=" -fn $font"
parameters+=" -ta c -bg $bgcolor -fg $fgcolor"
parameters+=" -title-name dzentop"

# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----
# main

# remove all dzen2 instance
pkill dzen2

generated_output | dzen2 $parameters &

This step also add system command that kill any previous dzen2 instance. So it will be guaranteed, that the dzen2 shown is coming from the latest script.

Similar Code: [ BASH fork ] [ Perl fork ] [ Python fork ] [ Ruby fork ] [ PHP fork ] [ Lua fork ] [ Haskell fork ]


Polishing The Script

This step, we use conky again, as a source feed. And also parameterized dzen2 as continuation of previous step.

This step add optional transset transparency, detached from script. So we two forks, dzen and transset.

Source:

#!/usr/bin/env bash

generated_output() {
    dirname=$(dirname $(readlink -f "$0"))
    path="$dirname/../assets"
    conky -c "$path/conky.lua"
}

# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----
# parameters

xpos=0
ypos=0
width=640
height=24
fgcolor="#000000"
bgcolor="#ffffff"
font="-*-fixed-medium-*-*-*-12-*-*-*-*-*-*-*"

parameters="  -x $xpos -y $ypos -w $width -h $height" 
parameters+=" -fn $font"
parameters+=" -ta c -bg $bgcolor -fg $fgcolor"
parameters+=" -title-name dzentop"

# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----
# main

# remove all dzen2 instance
pkill dzen2

# execute dzen
generated_output | dzen2 $parameters &

# optional transparency
sleep 1 && exec `(transset .8 -n dzentop >/dev/null 2>&1 &)` & 

This would have dzen2 output similar to this below.

Pipe: to Dzen2

Similar Code: [ BASH conky ] [ Perl conky ] [ Python conky ] [ Ruby conky ] [ PHP conky ] [ Lua conky ] [ Haskell conky ]


There above are some simple codes I put together. I’m mostly posting codes so I won’t have any problems finding it in the future.

Thank you for reading.