____________________

                        PUMP UP THE VOLUME

                           Nicolas Herry
                       ____________________


                            2017/12/27





1 Pump up the volume
====================

  I had an itch to scratch this morning: I wanted to play a bit
  with functions in the Korn Shell. After all, it's one of the
  reasons I decided to switch from the `tcsh' earlier this
  year. Then, I realised it's been a million years since I've
  written any shell, and even more so that I've read some `ksh'
  code. So, how does this work again? Below is a simple and quick
  memento on the very basics of `ksh' programming.


1.1 Declaring a function
~~~~~~~~~~~~~~~~~~~~~~~~

  This is as easy as:
  ,----
  | function M {
  |     echo "mixer"
  | }
  `----

  Alternatively, a function can be declared in a C-style form:
  ,----
  | M() {
  |     echo "mixer"
  | }
  `----
  There really is no difference between the two styles in terms of
  functionalities.


1.2 Piping to a function
~~~~~~~~~~~~~~~~~~~~~~~~

  Piping to a function is as easy as asking the function to read
  from standard input. This can be done as follows:
  ,----
  | function A {
  |     read stdin
  | }
  `----


1.3 Comparing strings
~~~~~~~~~~~~~~~~~~~~~

  Since `ksh' is POSIX-compliant, it implements the complete set of
  regex matching plumbing (and then some more, as I've
  discovered). A simple check goes like this:
  ,----
  | function R  {
  |     read stdin
  |     pattern='.*:$'
  |     vols=""
  | 	 
  |     if [[ $stdin =~ $pattern ]]; then
  |       # ...
  | }
  `----


1.4 Playing with numbers
~~~~~~~~~~~~~~~~~~~~~~~~

  This is another spot where I believe `ksh' goes beyond what is
  required by the POSIX standard. You can do any of the four basic
  operations, as well as more advanced stuff, like bit-shifting or
  bitwise logic. Anyting between `$((' and `))' is considered to be
  an arithmetic expression. Here's an example:
  ,----
  | function R {
  |     # ...
  |     if [[ $stdin =~ $pattern ]]; then
  |       volr=$(($RANDOM & 15));
  |       vols="${stdin}+${volr}";
  |     else
  |       voll=$(($RANDOM & 15));
  |       vols="${stdin} +${voll}:";
  |     fi
  |     
  |     echo $vols
  | }
  `----
  The interesting bit is the `&', which is the same operator you
  find in languages like C. Note that the Korn shell also provides
  an easy way to generate pseudo-random numbers via the usage of
  the reserved `$RANDOM' variable.


1.5 Capturing the output of a command
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  Capturing the ouput of a variable is done very intuitively:
  ,----
  | function S {
  | 	 read stdin
  | 	 result=$($stdin)
  | 	 echo $result
  | }
  `----


1.6 Making it all available
~~~~~~~~~~~~~~~~~~~~~~~~~~~

  To make your functions available to both your scripts and your
  interactive sessions, it is generally recommended you either
  group them in a nice set of files that would contitute a library,
  or give them each their own file. Place these files somewhere in
  your home (I would go for `~/functions', to go with `~/bin') and
  edit both `PATH' and `FPATH', in `~/.kshrc' or `~/.profile' to
  include this directory:
  ,----
  | # ~/.kshrc
  | # ...
  | # ...
  | PATH=$PATH:~/functions; export PATH
  | FPATH=$FPATH:~/functions; export PATH
  `----


1.7 Putting it together
~~~~~~~~~~~~~~~~~~~~~~~

  The last bit of advice I would give would be that when you lose
  patience, you don't lose your sense of humour. For example, if
  you've been paying attention ot the examples, you have already
  noticed that the complete set of functions goes like this:
  ,----
  | function M {
  | 	 echo "mixer"
  | }
  | 
  | function A {
  | 	 read stdin
  | 	 echo "$stdin vol"
  | }
  | 
  | function R {
  | 	 read stdin
  | 	 pattern='.*:$'
  | 	 vols=""
  | 	 
  | 	 if [[ $stdin =~ $pattern ]]; then
  | 	    volr=$(($RANDOM & 15));
  | 	    vols="${stdin}+${volr}";
  | 	 else
  | 	    voll=$(($RANDOM & 15));
  | 	    vols="${stdin} +${voll}:";
  | 	 fi
  | 	 echo $vols
  | }
  | 
  | function S {
  | 	 read stdin
  | 	 result=$($stdin)
  | 	 echo $result
  | }
  `----
  But how is this funny in any way? Simply because I can now do the
  following in a shell:
  ,----
  | $ M|A|R|R|S
  | Setting the mixer vol from 5:5 to 18:16.
  | $ 
  `----
  Yes, I can type `M|A|R|R|S' and [Pump up the volume][1]. I know.


[Pump up the volume]
<https://www.youtube.com/watch?v%3Dw9gOQgfPW4Y>



Footnotes
_________

[1] Well, a friend of mine didn't find this funny at all, but she
can get lost on another planet. As I've heard, Mar(r)s needs
women anyway.