How to write a bash script like the python?




                Lloyd Huang
       KaLUG - Kaohsiung Linux User Group
             COSCUP Aug 18 2012
Before the start


Before the start
 • About Bash Python and me.

 • The ipython and lpython.py.
 • A trick, but it touches my heart.
  Examples of lpython.py :
    cat /etc/passwd | lpython.py 
    'for i in stdin:n s=i.split(":"); print s[0],s[5],s[6],'

    uname -a | lpython.py 'print stdin.read().split()[0:3]'




                                                                 2
Bash: Questions and answers


Bash: Questions and answers

   Q: How to be more logic and reuse?
   A: Function.
   Q: How to do unit testing?
   A: Function.
   Q: How different is between
      Bash function and Python module?
   A: ....




                                                 3
Bash source VS Python import


Bash source VS Python import
Python
 • A module allows you to logically organize your Python
    code. Grouping related code into a module makes the
    code easier to understand and use.
 • Python modules are easy to create; they're just files
    of Python program code.
 • if __name__ == '__main__':




                                                        4
Bash source VS Python import




How Bash do it?




                                  5
Bash source VS Python import


#!/bin/bash              | #!/usr/bin/python
funtest() {              | def funtest():
    echo "func for test" |     print "func for test"
}                        |
funfake() {              | def funfake():
    echo "func for fake" |     print "func for fake"
}                        |
# main                   | if __name__ == '__main__':
funtest                  |     funtest()
funfake                  |     funfake()

$> source samp00.sh      $> python
func for test            >>> import samp00
func for fake

$> bash samp00.sh        $> python samp00.py
func for test            func for test
func for fake            func for fake


                                                         6
Bash source VS Python import


#!/bin/bash                |   #!/usr/bin/python
funtest() {                |   def funtest():
    echo "func for test"   |       print "func for test"
}                          |
funfake() {                |   def funfake():
    echo "func for fake"   |       print "func for fake"
}                          |
return 2> /dev/null        |   if __name__ == '__main__':
funtest                    |       funtest()
funfake                    |       funfake()

$> source samp00.sh        $> python
                           >>> import samp00


$> bash samp00.sh          $> python samp00.py
func for test              func for test
func for fake              func for fake


                                                             7
Bash source VS Python import


#!/bin/bash
funtest() {
    echo "func for test"
}
funfake() {
    echo "func for fake"
}
if [ "$0" == "$BASH_SOURCE" ]; then
    funtest
    funfake
fi

                                             8
From xkcd http://xkcd.com/353/
Python module and docstring


Python module and docstring

    • import, from
    • import module as someone
       – Import module
    • del
       – Delete object
    • docstring
       – Python Documentation Strings



                                                 10
Python module and docstring


#!/usr/bin/python
def funtest():
    """
    Here is python docstring for funtest.
    Here is python docstring for funtest.
    """
    print "func for test"

def funfake():
    "Here is python docstring for funcfake."
    print "func for fake"

if __name__ == '__main__':
    funtest()
    funfake()

                                                     11
Python module and docstring


$> python
>>> import samp02
>>> samp02.
samp02.__doc__( samp02.funtest( samp02.funfake(

>>> samp02.funtest()
func for test

>>> help (samp02.funtest)
>>>
Help on function funtest in module samp02:

funtest()
  Here is python docstring for funtest.
  Here is python docstring for funtest.

                                                   12
Python module and docstring


>>> samp02.funfake.__doc__
'Here is python docstring for funcfake.'
>>> print samp02.funfake.__doc__
Here is python docstring for funcfake.

>>> import samp02 as new_samp02
>>> new_samp02.funtest()
func for test

>>> del new_samp02
>>> new_samp02.funtest()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  NameError: name 'new_samp' is not defined



                                                   13
Bash import and docstring ?


Bash import and docstring ?

Usage: source import.sh
    • import, from
    • import module as someone
      – Import module
    • del module
      – Delete module
    • help module.function
      – Documentation Strings

                                                  14
Bash import and docstring ?


#!/bin/bash
funtest() {
    __doc__="
Here is bash import.sh docstring for funtest
Here is bash import.sh docstring for funtest
"
    echo "func for test"
}
funfake() {
   __doc__="Here is bash import.sh docstring for funfake"
    echo "func for fake"
}
if [ "$0" == "$BASH_SOURCE" ]; then
    funtest
    funfake
fi



                                                        15
Bash import and docstring ?


$> source import.sh
$> import samp02.sh
$> samp02
samp02.funfake samp02.funtest
$> samp02.funtest
func for test
$> import samp02.sh as new_samp
$> new_samp.funtest
func for test
$> help new_samp.funtest
Here is bash import.sh docstring for funtest
Here is bash import.sh docstring for funtest

$> del new_samp
$> new_samp.funtest
bash: new_samp.funtest command not found



                                                       16
uid, gid = split(``1000:100'',``:'') ?


uid, gid = split(``1000:100'',``:'') ?
Python : split
    name, passwd, uid, gid, note, homedir, shell =
    string.split(www-data:x:33:33:www-data:/var/www:/bin/sh,:)


Bash : read
    LDread () {
     __doc__=LDread '.' 'V01.01.05.28.KH0.10.28' c1 c2 c3 c4 c5 c6 c7

        local ifs con
        ifs=$1; shift
        con=$1; shift
        IFS=$ifs read $@  (echo $con)
    }



                                                                     17
阿宅圖片來源:公立怪咖國民小學 http://blog.xuite.net/protion/school/9142122
Hook


Hook
   #!/bin/bash
   funtest() {
       __doc__=Hook test - Part I
   PreHook=echo This is PreHook
   PostHook=echo This is PostHook

       test -n $PreHook  $PreHook
       echo func for test
       test -n $PostHook  $PostHook
   }




                                            19
Hook


$ import hook00.sh
$ hook00.funtest
func for test

$ help hook00.funtest
Hook test - Part I
PreHook=echo This is PreHook
PostHook=echo This is PostHook

$ PreHook=echo This is PreHook
$ PostHook=echo This is PostHook
$ hook00.funtest
This is PreHook
func for test
This is PostHook

                                        20
Hook


#!/bin/bash
funtestPreHook () {
    return
}
funtestPostHook () {
    return
}
funtest() {
    __doc__=Hook test - Part II
funtestPreHook () { echo This is funtestPreHook; }
funtestPostHook () { echo This is funtestPostHook; } 

    funtestPreHook
    echo func for test
    funtestPostHook
}




                                                               21
Hook


$ import hook01.sh
$ hook01.funtest
func for test

$ help hook01.funtest
Hook test - Part II
hook01.funtestPreHook () { echo This is funtestPreHook; }
hook01.funtestPostHook () { echo This is funtestPostHook; }

$ hook01.funtestPreHook () { echo This is funtestPreHook; }
$ hook01.funtestPostHook () { echo This is funtestPostHook; }
$ hook01.funtest
This is funtestPreHook
func for test
This is funtestPostHook




                                                        22
Demo


Demo




         23
Advantages VS Problems


Advantages VS Problems
    • Advantages
      – Function reuse
      – Unit testing
      – Name space
      – Documentation strings
      – Grouping up commands
    • Problems
      – To Conflict with ImageMagick
      – Can't work with busybox ash



                                                 24

COSCUP2012: How to write a bash script like the python?

  • 1.
    How to writea bash script like the python? Lloyd Huang KaLUG - Kaohsiung Linux User Group COSCUP Aug 18 2012
  • 2.
    Before the start Beforethe start • About Bash Python and me. • The ipython and lpython.py. • A trick, but it touches my heart. Examples of lpython.py : cat /etc/passwd | lpython.py 'for i in stdin:n s=i.split(":"); print s[0],s[5],s[6],' uname -a | lpython.py 'print stdin.read().split()[0:3]' 2
  • 3.
    Bash: Questions andanswers Bash: Questions and answers Q: How to be more logic and reuse? A: Function. Q: How to do unit testing? A: Function. Q: How different is between Bash function and Python module? A: .... 3
  • 4.
    Bash source VSPython import Bash source VS Python import Python • A module allows you to logically organize your Python code. Grouping related code into a module makes the code easier to understand and use. • Python modules are easy to create; they're just files of Python program code. • if __name__ == '__main__': 4
  • 5.
    Bash source VSPython import How Bash do it? 5
  • 6.
    Bash source VSPython import #!/bin/bash | #!/usr/bin/python funtest() { | def funtest(): echo "func for test" | print "func for test" } | funfake() { | def funfake(): echo "func for fake" | print "func for fake" } | # main | if __name__ == '__main__': funtest | funtest() funfake | funfake() $> source samp00.sh $> python func for test >>> import samp00 func for fake $> bash samp00.sh $> python samp00.py func for test func for test func for fake func for fake 6
  • 7.
    Bash source VSPython import #!/bin/bash | #!/usr/bin/python funtest() { | def funtest(): echo "func for test" | print "func for test" } | funfake() { | def funfake(): echo "func for fake" | print "func for fake" } | return 2> /dev/null | if __name__ == '__main__': funtest | funtest() funfake | funfake() $> source samp00.sh $> python >>> import samp00 $> bash samp00.sh $> python samp00.py func for test func for test func for fake func for fake 7
  • 8.
    Bash source VSPython import #!/bin/bash funtest() { echo "func for test" } funfake() { echo "func for fake" } if [ "$0" == "$BASH_SOURCE" ]; then funtest funfake fi 8
  • 9.
  • 10.
    Python module anddocstring Python module and docstring • import, from • import module as someone – Import module • del – Delete object • docstring – Python Documentation Strings 10
  • 11.
    Python module anddocstring #!/usr/bin/python def funtest(): """ Here is python docstring for funtest. Here is python docstring for funtest. """ print "func for test" def funfake(): "Here is python docstring for funcfake." print "func for fake" if __name__ == '__main__': funtest() funfake() 11
  • 12.
    Python module anddocstring $> python >>> import samp02 >>> samp02. samp02.__doc__( samp02.funtest( samp02.funfake( >>> samp02.funtest() func for test >>> help (samp02.funtest) >>> Help on function funtest in module samp02: funtest() Here is python docstring for funtest. Here is python docstring for funtest. 12
  • 13.
    Python module anddocstring >>> samp02.funfake.__doc__ 'Here is python docstring for funcfake.' >>> print samp02.funfake.__doc__ Here is python docstring for funcfake. >>> import samp02 as new_samp02 >>> new_samp02.funtest() func for test >>> del new_samp02 >>> new_samp02.funtest() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'new_samp' is not defined 13
  • 14.
    Bash import anddocstring ? Bash import and docstring ? Usage: source import.sh • import, from • import module as someone – Import module • del module – Delete module • help module.function – Documentation Strings 14
  • 15.
    Bash import anddocstring ? #!/bin/bash funtest() { __doc__=" Here is bash import.sh docstring for funtest Here is bash import.sh docstring for funtest " echo "func for test" } funfake() { __doc__="Here is bash import.sh docstring for funfake" echo "func for fake" } if [ "$0" == "$BASH_SOURCE" ]; then funtest funfake fi 15
  • 16.
    Bash import anddocstring ? $> source import.sh $> import samp02.sh $> samp02 samp02.funfake samp02.funtest $> samp02.funtest func for test $> import samp02.sh as new_samp $> new_samp.funtest func for test $> help new_samp.funtest Here is bash import.sh docstring for funtest Here is bash import.sh docstring for funtest $> del new_samp $> new_samp.funtest bash: new_samp.funtest command not found 16
  • 17.
    uid, gid =split(``1000:100'',``:'') ? uid, gid = split(``1000:100'',``:'') ? Python : split name, passwd, uid, gid, note, homedir, shell = string.split(www-data:x:33:33:www-data:/var/www:/bin/sh,:) Bash : read LDread () { __doc__=LDread '.' 'V01.01.05.28.KH0.10.28' c1 c2 c3 c4 c5 c6 c7 local ifs con ifs=$1; shift con=$1; shift IFS=$ifs read $@ (echo $con) } 17
  • 18.
  • 19.
    Hook Hook #!/bin/bash funtest() { __doc__=Hook test - Part I PreHook=echo This is PreHook PostHook=echo This is PostHook test -n $PreHook $PreHook echo func for test test -n $PostHook $PostHook } 19
  • 20.
    Hook $ import hook00.sh $hook00.funtest func for test $ help hook00.funtest Hook test - Part I PreHook=echo This is PreHook PostHook=echo This is PostHook $ PreHook=echo This is PreHook $ PostHook=echo This is PostHook $ hook00.funtest This is PreHook func for test This is PostHook 20
  • 21.
    Hook #!/bin/bash funtestPreHook () { return } funtestPostHook () { return } funtest() { __doc__=Hook test - Part II funtestPreHook () { echo This is funtestPreHook; } funtestPostHook () { echo This is funtestPostHook; } funtestPreHook echo func for test funtestPostHook } 21
  • 22.
    Hook $ import hook01.sh $hook01.funtest func for test $ help hook01.funtest Hook test - Part II hook01.funtestPreHook () { echo This is funtestPreHook; } hook01.funtestPostHook () { echo This is funtestPostHook; } $ hook01.funtestPreHook () { echo This is funtestPreHook; } $ hook01.funtestPostHook () { echo This is funtestPostHook; } $ hook01.funtest This is funtestPreHook func for test This is funtestPostHook 22
  • 23.
  • 24.
    Advantages VS Problems AdvantagesVS Problems • Advantages – Function reuse – Unit testing – Name space – Documentation strings – Grouping up commands • Problems – To Conflict with ImageMagick – Can't work with busybox ash 24