Tuesday, August 31, 2010

[Level 2] Bash completion in Ubuntu

As we know, we can use "tab" for word completion.
And now, you can also use "tab" for bash completion.
That means when you finished typing your command,
ex. # apt-get
and you press "tab", then you will get the options for apt-get.
# apt-get
autoclean        clean            purge            upgrade
autoremove       dist-upgrade     remove          
build-dep        dselect-upgrade  source          
check            install          update

How could you enable this feature?
add the following command in your ~/.bashrc, if not exists.
if [ -f /etc/bash_completion ] then;
    . /etc/bash_completion
fi


Wish this helps.
regards,
Stanley Huang

Sunday, August 29, 2010

[Level 2] Math exam generator

This morning, my son ask me to give him a 50 question math exam.
So I wrote a math exam generator to produce the exam.
PS. You need OpenOffice to open result file.

#!/bin/bash
set -f
declare -i nQ=${1:-50}
declare    sF=$0.csv; [ -f $sF ] && rm $sF;
declare -i i=0
declare    aOperator=(+ - * /); declare -i nOperator=4
declare    aOperator=(+ -); declare -i nOperator=2

getRandomNumber() {
  declare -i n=$RANDOM*89/32767+10
  echo $n
}

getRandomOperator() {
  declare -i n=$RANDOM*$nOperator/32767
  echo ${aOperator[$n]}
}

for i in `seq 1 $nQ`
do
  declare -i n1=`getRandomNumber`
  declare -i n2=`getRandomNumber`
  declare    sO=`getRandomOperator`
  echo "$n1,$sO,$n2,=,,=if(isblank(e$i);0;if(e$i=(a$i${sO}c$i);1;0))" >> $sF
done
echo ",,,correct,=,=sum(f1:f$i),/$i" >> $sF
echo ",,,score,=,=sum(f1:f$i)/$i*100" >> $sF
soffice $sF


Wish this helps.
regards,
Stanley Huang

Monday, August 16, 2010

[Level 1] Upgrade GNOME desktop from 2 to 3 in Ubuntu.

Upgrade your GNOME desktop from 2 to 3.
  • sudo apt-get build-dep gnome-shell
  • sudo apt-get install gnome-shell
  • gnome-shell --replace

Wish this helps.
regards,
Stanley Huang

[Level 1] OpenSolaris is died?!

In these days, friends of mine asked about "Is OpenSolaris is died?".
My answer is, "OpenSolaris" is died, but the spirit of "Open" "Solaris" is never die.
Because some boarders of OpenSolaris, host a new project call "IllumOS".
If you like OpenSolaris, IllumOS might be your best choice.

Wish this helps.
regards,
Stanley Huang

Thursday, August 5, 2010

[Level 3] Menu Bash Script

One day, one friend of mine ask me how to create a menu with timeout limitation in bash, then I wrote the sample code for him.
I think this maybe a good idea if I can write a menu bash script with dynamic setting menu item and so on.
Therefore I write the script below, any feedback will be appreciate.

#!/bin/bash

##############################################
##
## for menu utility
##
## author: Stanley Huang
## licence: Creative Commons Attribution-Share Alike 3.0 Taiwan License
## last release reversion: 0.1
## last modify date: 2010/08/04 15:30
## change list:
##   01. 2010/08/04 15:30, Stanley Huang. Build.
##
##############################################

showUsage() {
  cat<<EOF
Usage:
  $0
     [-e] (expert mode)
     [-h] (help menu)
     [-t] timeout_sec (default timeout = $nTimeout sec)
     [-c] no. of columns to display (default no. of column = $nColumn)
     [-w] column wide (default column wide = $nWide)
     [-m] menu file
Ex.
  $0
  $0 -e
  $0 -h
  $0 -t 10
  $0 -c 3
  $0 -w 10
  $0 -m /tmp/t.menu
EOF
}

pak2c() {
  read -n 1 -p "Press any key to continue..." pak2c
}

checkItemExist() {
  local sItem=$1
  grep "^$sFilter$sItem$sMenuActSeparator" $sMenuFile > /dev/null 2>&1
  return $?
}

checkItemNotExist() {
  local sItem=$1
  checkItemExist $sItem
  if [ $? -eq 0 ]
  then
    return 1
  else
    return 0
  fi
}

getHeader() {
  local sHeader="`grep "^$sHeaderFilter" $sMenuFile | head -1 | cut -d' ' -f2-`"
  echo $sHeader
}

setHeader() {
  while true
  do
    read -p "Please enter your header: " sNewHeader
    [ ! -z "$sNewHeader" ] && break
  done
  sHeader=$sNewHeader
  if [ `grep -c "^$sHeaderFilter" $sMenuFile` -ne 0 ]
  then
    perl -pi -e "s/^$sHeaderFilter.*$/$sHeaderFilter$sNewHeader/" $sMenuFile
  else
    echo "$sHeaderFilter$sNewHeader" >> $sMenuFile
  fi
}

buildMenu() {
  clear
  declare -i nColumn=$1
  declare -i nWide=$2
  declare -i nCount=0
  declare -i nMod=0
  declare    sCount=""

  printf -- "$sOuterSeparatorLine\n" && \
  printf -- "        `getHeader`\n" && \
  printf -- "$sOuterSeparatorLine\n" && \

  while read fItem item
  do
    nCount=$nCount+1 && sCount=$nCount && [ $isExpert -eq 0 ] && sCount=.
    aMenu[$nCount]="`echo $item | awk -F$sMenuActSeparator '{print($1)}'`"
    aActs[$nCount]="`echo $item | awk -F$sMenuActSeparator '{print($2)}'`"
   
    fDisable=`echo $fItem | sed -e 's/[^*]//g'`
    printf "%${#nTotalCount}s) %${nWide}s%1s" $sCount ${aMenu[$nCount]} $fDisable
   
    nMod=$nCount%$nColumn
    if [ $nMod -eq 0 ]
    then
      printf "\n";
    else
      printf " ";
    fi
  done <<EOF
`grep "^$sFilter" $sMenuFile ## disable display with sorting`
EOF
  #### `grep "^$sFilter" $sMenuFile | sort -k 2 ## display with sorting`
  [ $nMod -ne 0 ] &&  printf "\n"

  printf -- "$sOuterSeparatorLine\n" && \
  if [ "$isExpert" -eq 0 ]
  then
    printf "%${#nTotalCount}s) %${nWide}s\n" "a" "(A)dd"
    printf "%${#nTotalCount}s) %${nWide}s\n" "c" "(C)hange name"
    printf "%${#nTotalCount}s) %${nWide}s%s\n" "d" "(D)isable" ", marked *"
    printf "%${#nTotalCount}s) %${nWide}s\n" "e" "(E)nable"
    printf "%${#nTotalCount}s) %${nWide}s\n" "h" "set (H)eader"
    printf "%${#nTotalCount}s) %${nWide}s\n" "m" "(M)odify"
    printf "%${#nTotalCount}s) %${nWide}s\n" "r" "(R)emove"
    printf "%${#nTotalCount}s) %${nWide}s\n" "s" "(S)ort data"
    printf "%${#nTotalCount}s) %${nWide}s\n" "v" "(V)iew cmd"
    printf -- "$sInnerSeparatorLine\n"
    printf "%${#nTotalCount}s) %${nWide}s\n" "n" "(N)ormal mode"
  else
    printf "%${#nTotalCount}s) %${nWide}s\n" "e" "(E)xpert mode"
  fi
  printf "%${#nTotalCount}s) %${nWide}s\n" "q" "(Q)uit"
  printf -- "$sOuterSeparatorLine\n"
}

## Usage:
##   repeat [character] [line size]
## Ex.
##   repeat x 100
repeat() {
  [ $# -lt 2 ] && return 1
  sChar=${1:0:1}
  nSize=$2
  printf -vch  "%${nSize}s" ""
  printf "%s\n" "${ch// /$sChar}"
}

############################################# main

clear
set -o noglob
declare -i nDefaultTimeout=10
declare -i nExpertTimeout=65535
declare -i nTimeout=$nDefaultTimeout
declare -i isExpert=1
declare -a aMenu
declare -a aActs
declare    sMenuActSeparator=":"
declare    sFilter=""
declare -i nTotalCount=0
declare -i nDefaultColumn=1
declare -i nExpertColumn=3
declare -i nColumn=$nDefaultColumn
declare -i nWide=16
declare -i nActionWide=20
declare    sMenuFile=$0 ## default menu file is program itself.

declare -i nSeparatorLength=30
declare    sOuterSeparatorLine=`repeat = $nSeparatorLength`
declare    sInnerSeparatorLine=`repeat - $nSeparatorLength`

while getopts ":ehc:t:w:m:" opt
do
  case $opt in
  e)
    isExpert=0
    ;;
  h)
    showUsage
    exit 0
    ;;
  c)
    nDefaultColumn=$OPTARG
    ;;
  m)
    sMenuFile=$OPTARG
    ;;
  t)
    nDefaultTimeout=$OPTARG
    ;;
  w)
    nWide=$OPTARG
    ;;
  :)
    echo "The option ($opt) without parameters, exit program..."
    showUsage
    exit 1
    ;;
  \?)
    echo "Not such option($OPTARG), exit program..."
    showUsage
    exit 1
    ;;
  esac
done

sEnableFilter="#@ "
sDisableFilter="#\* "
sNormalFilter=$sEnableFilter
sExpertFilter="#[@*][ ]"
sExpertFilter4Perl="(#[@*][ ])"
sHeaderFilter="#\^ "
if [ $isExpert -eq 0 ]
then
  sFilter=$sExpertFilter
  nTimeout=$nExpertTimeout
  nColumn=$nExpertColumn
else
  sFilter=$sEnableFilter
  nTimeout=$nDefaultTimeout
  nColumn=$nDefaultColumn
fi
nTotalCount=`grep -c "^$sFilter" $sMenuFile`

while true
do
  buildMenu $nColumn $nWide
  declare -i nChoice
  declare    sChoice
  declare -i fRead=0
  declare    sItem=""

  while true
  do
    echo -n "Please enter your choice ($nTimeout secs to timeout): "
    read -t $nTimeout sChoice || fRead=$?

    #### special events
    [ $fRead -eq 142 ] && echo "Time out..." && exit 0
    [ $isExpert -eq 1 ] && [ $sChoice == 'e' ] && $0 -e -t $nDefaultTimeout -m $sMenuFile && exit 0
    [ $isExpert -eq 0 ] && [ $sChoice == 'n' ] && $0 -t $nDefaultTimeout -m $sMenuFile && exit 0
    [ $sChoice == 'q' ] && exit 0

    #### choice reactions
    nChoice=$sChoice
    [ -z "$sChoice" ] && buildMenu $nColumn $nWide && continue
    [ $isExpert -eq 1 ] && ( [ $nChoice -le 0 ] || [ $nChoice -gt $nTotalCount ] ) && continue
    [ $isExpert -eq 0 ] && ( [ $sChoice == "0" ] || [ $nChoice -ne 0 ] ) && continue
    break
  done

  case "$sChoice" in
  a)
    while true
    do
      read -p "Please enter the item you want to add: " sItem
      [ -z $sItem ] && break
      checkItemExist "$sItem" || break
      echo "Item ($sItem) exist!!"
    done

    if [ ! -z $sItem ]
    then
      read -p "Please enter the action of the item you added: " sAct
      if [ ! -z $sAct ]
      then
        echo "$sEnableFilter$sItem$sMenuActSeparator$sAct" >> $sMenuFile
        echo "Add item ($sItem) done..."
      fi
    fi
    ;;
  c)
    while true
    do
      read -p "Please enter the item you want to rename: " sItem
      [ -z $sItem ] && break
      checkItemNotExist "$sItem" || break
      echo "Item ($sItem) doesnot exist!!"
    done

    if [ ! -z $sItem ]
    then
      read -p "Please enter the new name of the item: " sNewItemName
      perl -pi -e "s/^$sExpertFilter4Perl$sItem$sMenuActSeparator.*$/\1$sNewItemName$sMenuActSeparator$sAct/" $sMenuFile
      echo "change item name ($sItem -> $sNewItemName) done..."
    fi
    ;;
  d)
    while true
    do
      read -p "Please enter the item you want to disable: " sItem
      [ -z $sItem ] && break
      checkItemNotExist "$sItem" || break
      echo "Item ($sItem) doesnot exist!!"
    done

    if [ ! -z $sItem ]
    then
      perl -pi -e "s/^$sEnableFilter$sItem$sMenuActSeparator/$sDisableFilter$sItem$sMenuActSeparator/" $sMenuFile
      echo "disable item ($sItem) done..."
    fi
    ;;
  e)
    while true
    do
      read -p "Please enter the item you want to enable: " sItem
      [ -z $sItem ] && break
      checkItemNotExist "$sItem" || break
      echo "Item ($sItem) doesnot exist!!"
    done

    if [ ! -z $sItem ]
    then
      perl -pi -e "s/^$sDisableFilter$sItem$sMenuActSeparator/$sEnableFilter$sItem$sMenuActSeparator/" $sMenuFile
      echo "enable item ($sItem) done..."
    else
      echo "sItem is empty..."
    fi
    ;;
  h)
    setHeader
    ;;
  m)
    while true
    do
      read -p "Please enter the item you want to modify: " sItem
      [ -z $sItem ] && break
      checkItemNotExist "$sItem" || break
      echo "Item ($sItem) doesnot exist!!"
    done

    if [ ! -z $sItem ]
    then
      read -p "Please enter the action of the item: " sAct
      perl -pi -e "s/^$sExpertFilter4Perl$sItem$sMenuActSeparator.*$/\1$sItem$sMenuActSeparator$sAct/" $sMenuFile
      echo "modify item ($sItem) done..."
    fi
    ;;
  r)
    while true
    do
      read -p "Please enter the item you want to remove: " sItem
      [ -z $sItem ] && break
      checkItemNotExist "$sItem" || break
      echo "Item ($sItem) doesnot exist!!"
    done

    if [ ! -z $sItem ]
    then
      perl -pi -e "s/^$sExpertFilter$sItem$sMenuActSeparator.*\n$//" $sMenuFile
      echo "remove item ($sItem) done..."
    fi
    ;;
  s)
    cp $sMenuFile $sMenuFile.bak ## backup first
    declare -i nEOS=`grep -n '#### \*\*\* Data \*\*\*$' $sMenuFile | cut -d: -f1`
    declare -i nBOD=$nEOS+1 ## not work for Ubuntu
    declare -i nLOD=`wc -l $sMenuFile | awk '{print($1)}'`-$nEOS
    [ $nEOS -eq 0 ] && exit 0
    head -$nEOS $sMenuFile > /tmp/$$.main
    ##tail +$nBOD $sMenuFile | sed -e "s/^#[@*][ ]*$//" | sed -e "/^$/d" | sort -k 2 > /tmp/$$.data ## not work for Ubuntu
    tail -$nLOD $sMenuFile | sed -e "s/^$sExpertFilter*$//" | sed -e "/^$/d" | sort -k 2 > /tmp/$$.data
    cat /tmp/$$.main /tmp/$$.data > $sMenuFile
    rm /tmp/$$.main /tmp/$$.data
    echo "Sorting data done, please restart your program..."
    ;;
  v)
    while true
    do
      read -p "Please enter the item you want to view: " sItem
      [ -z $sItem ] && break
      checkItemNotExist "$sItem" || break
      echo "Item ($sItem) doesnot exist!!"
    done

    if [ ! -z $sItem ]
    then
      grep "^$sExpertFilter$sItem$sMenuActSeparator" $sMenuFile | awk -F"$sMenuActSeparator" '{print("Command:",$2)}'
    fi
    ;;
  "")
    ;;
  *)
    if [ $isExpert -eq 1 ] ## 1 for not expert mode!
    then   
      OLD_IFS=$IFS
      IFS=';'
      for sCmdOpts in ${aActs[$nChoice]}
      do
        echo "Execute Command: $sCmdOpts"
        eval $sCmdOpts
      done
      IFS=$OLD_IFS
    else
      continue
    fi     
    ;;
  esac
  pak2c
done

echo "End of process..."

exit
exit
exit

####
#### Menu item:
####   Use '#@ ', '#* ' at the begin of the line for setting menu item
####   #^ header(title)
####   #@ enable items
####   #* disable items
#### Ex.
####   #@ item
#### PS.
####   Do not modify the data below, use option "-e" (export mode) to modify.
####
#### *** Header ***
#^ My Menu
####
#### *** Data ***
#@ apple:echo "this an apple"
#@ banana:echo "this an banana"
#@ ls:ls
#@ id:id
#@ pwd:pwd
#@ stanley:id;pwd;ls -al;ls ./;echo 1 2 3;pwd;id

Wish this helps.
regards,
Stanley Huang