聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

十月 4, 2011
» What’s new in Python UCLTIP-0.6?

Summary

After 0.5 released, I did so much exercise in my holidays, like hiking,
swimming, those less my hacking time, so ucltip development became very slowly recently,

which means 0.6 does not have too much changes!

New Feature: Pipeline

In subprocess, the way for doing pipeline is

?View Code PYTHON
>>> p1 = Popen(["dmesg"], stdout=PIPE)
>>> = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
>>>output = p2.communicate()[0]

which is not convenience when you want to pipe many commands.

Pipe class provide similar interface as C library `libpipeline` (http://libpipeline.nongnu.org/)
that manipulating pipelines of subprocesses in a flexible and convenient way in C.

firstly, you need to create a Pipe instance

?View Code PYTHON
>>>pipe = ucltip.Pipe()

and then add some command arguments as you want

?View Code PYTHON
>>>pipe.add('expr', 1, '+' 3)
>>>pipe.add('sed', 's/4/5/', '--posix')

finally run the process, wait it terminate and get its output

?View Code PYTHON
>>>pipe.wait()
>>>pipe.stdout.read()
5

the first argument of Pipe.add function can be Cmd or SubCmd,
please remaind the usage of add function is changed in this case

Receive first arguments is instance of Cmd

?View Code PYTHON
>>>pipe = ucltip.Pipe()
>>>pipe.add(Cmd('expr'), 1, '+', 3)
>>>pipe.add(Cmd('sed'), 's/4/5', posix=True)
>>>pipe.wait()
>>>pipe.stdout.read()
5

Receive first arguments is instance of SubCmd

?View Code PYTHON
>>>apt_cache = ucltip.CmdDispatcher('apt-cache')
>>>pipe = ucltip.Pipe()
>>>pipe.add(apt_cache.search, 'vim-common')
>>>pipe.add(Cmd('grep'), 'vim')
>>>pipe.wait()
>>>pipe.stdout.read()

New Feature: Global Config

executing mode setting:

There are 3 type ofexecuting behavior of Cmd or CmdDispatcher, each are

  1. ‘process’: produce command string and execute (default)
  2. ‘list’, : only produce command arguments list
  3. ‘string’ : only produce command string

Example of list mode:

?View Code PYTHON
# produce command arguments only, same as dry_run
>>>ucltip.global_config(execmod='list')
>>>ucltip.Cmd('ls')(a=True)
['ls', '-a']

Example of string mode:

?View Code PYTHON
# produce command string only
>>>ucltip.global_config(execmod='string')
>>>ucltip.Cmd('ls')(a=True)
'ls -a'

debug mode setting:

?View Code PYTHON
>>>import ucltip
>>>ucltip.global_config(debug=True)
>>>ucltip.Cmd('ls')()

the debug message will be storaged in /var/log/syslog as the following

1896 Oct  4 21:36:53 host python: UCLTIP: Created a Cmd object bound 'ls'
1897 Oct  4 21:36:53 host python: UCLTIP: Trasform Kwargs:input:{}, result:[]
1898 Oct  4 21:36:53 host python: UCLTIP: Builded command string:['ls']

it includes

  1. command be bound
  2. the keyword arguments to command options transform input and output
  3. produced command line string

New Feature: Logging

The error message will also be logged in /var/log/syslog by default as the following

1899 Oct  4 21:42:53 host python: UCLTIP: Executed "ls --nonop" failed, Err Msg:ls: unrecognized option '--nonop'#012Try `ls -     -help' for more information.

API Changes

Rename ‘interact’ parameter to ‘as_process’ of Cmd and CmdDispatcher.execute method for better understanding

?View Code PYTHON
>>>import ucltip
>>>ls=ucltip.Cmd('ls')
#old:
>>>proc=ls(interact=True)
#new:
>>>proc=ls(as_process=True)

How to install

Source Code released in http://pypi.python.org/pypi/ucltip, and
Debian unstable user can ‘python-ucltip’ package very soon.

六月 29, 2011
» Python UCLTIP 0.5 Release

Forward

I am glade to announce that ucltip python module 0.5 version is released in PyPi , and you will find it in Debian Unstable as soon as possible, the debian package is just upload by my sponsor Paul Liu two days ago, thanks for his great help.

What’s New in 0.5:

I did a lot of code refactoring , so please re-reading the module documentation!

  1. removed GNU license words in source code, because this module is under BSD 2-clause
  2. reg_singlecmds function is renamed as regcmds, and add a new parameter cls to control what type object will be generated
  3. SingleCmd is renamed as Cmd
  4. opt_style, dry_run attributes of Cmd(It is SingleCmd before 0.5) and CmdDispatcher is moved to new class CmdConfiguration, which is an data object for sharing common settings between objects.
  5. introduce new function opts of Cmd, CmdDispatcher for setting default options

for more details, please check README.txt in source code, or here. enjoy it

Feature Interesting Works

This module still has some task to make it better, if you have an good idea, please let me know. patchs are welcome.

JAVA options style

In Python Conference Taiwan 2011, yureju just asked does this module support JAVA options style, until 0.5 version , this module only support POSIX and GNU style, and I did some works in develop branch of github but did not find a good way to support it, JAVA option style is kinda massey.

Mix-in option style

some command like tar, its options has POSIX style and GNU style, also need to solve it. :)

PIPE!

we know pipe is really useful in Unix world, , unfortunately it is not easy used with subprocess module, since  ucltip is based on subprocess module, so the same, pipe is difficult used in ucltip.

 

六月 25, 2011
» Pyctw2011 UCLTIP簡報

2011/6/25 在 PycTW 2011 講了"UCLTIP",本次跟OSDC時說得差別只在一些用法稍稍變動, 還有多了可以為command設定default的options

下面則是當天Demo用的 Example Code:

?View Code PYTHON
#!/usr/bin/env python
#適用0.5rc1以下
from ucltip import *
 
# Result is string When execute Succeses
def ex_get():
    expr = Cmd('expr')
    result = expr(7, '+', 3)
    print result
    print int(result.replace("\n", ""))
 
# Raise Exception when the executed return code is not 0.
def ex_err():
    expr = Cmd('expr')
    try:
        result = expr('A', '+', 3)
    except CommandExecutedFalur as e:
        print "Return code:%d"%e.status
        print "Error message is %s"%e.errmsg
 
def ex_zenity1():
    zenity = CmdDispatcher('zenity')
    zenity.subcmd_prefix = '--'
    zenity.conf.opt_style = 1
    zenity.conf.dry_run=True
    print zenity.info(text='hello')
 
def ex_zenity2():
    zenity = CmdDispatcher('zenity')
    zenity.subcmd_prefix = '--'
    zenity.conf.opt_style = 1
    res = zenity.entry()
    print res
 
#Use Helper to create Cmd
def ex_helper1():
    regcmds('uname')
    print uname(a=True)
 
#Use Helper to create CmdDispatcher
def ex_helper2():
    regcmds('apt-get', 'apt-cache', cls=CmdDispatcher)
    apt_get.conf.dry_run=True
    apt_cache.conf.dry_run=True
    print apt_cache.search('vim')
    print apt_get.install('vim')
 
#Create custom class
def ext_cls():
    import datetime
    class Zenity(CmdDispatcher):
        def __init__(self):
            super(Zenity, self).__init__('zenity')
            self.conf.opt_style=1
            self.subcmd_prefix='--'
 
        def print_calendar(self,*args, **kwargs):
            try:
                ret = map(int, self.calendar(*args, **kwargs).replace('\n', '').split('/'))
                return datetime.datetime(ret[2],ret[0],ret[1])
            except CommandExecutedFalur as e:
                return False
 
    z=Zenity()
    date = z.print_calendar(text='Helllo!!!!!!', year=2015)
    print date
    print type(date)
 
if __name__ == '__main__':
    import sys
    import os
    try:
        func = sys.argv[1]
    except IndexError:
        print "USAGE: {} funcname".format(os.path.basename(__file__))
    else:
        try:
            eval(func)()
        except NameError:
            print 'can not find example function'


三月 27, 2011
» OSDC 2011 How to use command line tool 簡報上線

參加了這麼多年 OSDC,第一次以講者身份上台。
大致上是介紹自己在用Python做系統管理上的實務經驗,以及延伸出來解法。

OSDC這兩天感冒得很嚴重,講得需要加強(雖然本來就不太會簡報),
而且滿多英文Term發音是錯的(I don’t care, I speak Chinese!),希望聽眾有聽懂這場 Talk 是在說什麼 。

比較意外的是我是在大會議室講而不是小會議室,實在是誠荒誠恐,雖然我這場人數其實也不多啦! :p

這一次其實是自己給自己的生日禮物,因為演講日前一天是我的 27 歲生日。

另外, 我希望以後生日蛋糕上的蠟燭都是問號!!!!!!


十二月 16, 2010
» UCLTIP – Use command line tool in Python

Description

This library makes you use command line tool in Python more easier.
The original idea and most of basic codes are from GitPython project
`http://pypi.python.org/pypi/GitPython/`

  1. PyPi web: http://pypi.python.org/pypi/ucltip/
  2. Source repo: http://github.com/hychen/ucltip.git

Installation

  1. download tarbar
  2. user@host# ./setup install

Basic Usage

?View Code PYTHON
# without options
uname = SingleCmd('uname')
# result is Linux
print uname()
 
# with args
expr  = SingleCmd('expr')
# result is 10
print expr(7, '+', 3)
 
# with options, the style is '-a - l'
# example: ls -a -l
ls = SingleCmd('ls')
# enable debug mode to see what command string will be executed.
# show the debug message like this: DBG: execute cmd 'ls -a -l'
ls.__DEBUG__ = True
print ls(l=True, a=True)
 
# with boolean options, the style is 'ls --all --almost-all'
# variable has '-' should replaced by '_', otherwise syntax error happens
print ls(all=True, almost_all=True)
 
# with key-value optons, has 2 different style,
# `--key value` or `--key=value`, you can use opt_style variable to control them
wget = SingleCmd('wget')
 
# replacement of wget -o log http://url
wget('http://url', o='log')
 
# replacement of wget -o log=http://url
wget = SingleCmd('wget', opt_style=1)
wget('http://url', o='log')
 
# you can also overwrite the bound command
ls.cmdname = 'echo'
# the result is
# DBG: execute cmd 'echo hi'
#'hi\n'
print ls("hi")

The command be executed by subprocess.call, it bypass the shell.

?View Code PYTHON
# the result is $HOME, and it will not show output directly
print SingleCmd('echo')("$HOME")

if you want execute command via shell and use shell enviroment variable, please do as follow, if args of function includes `via_shell=True`, the command be executed by os.system

?View Code PYTHON
# the result is "/home/somebody", and show output directly
SingleCmd('echo')("$HOME", via_shell=True)

And here is the replacement if you want to do pipe for mutiple commands

?View Code PYTHON
ls = SingleCmd('ls')
grep = SingleCmd('grep')
# the result is setup.py
print grep('setup.py', stdin=ls(a=True, interact=True).stdout))
 
#p.s ls(a=True, interact=True) return a Popen instance, so you can have more control
#    of that process

Handling Error of command execution

if the command you want to use is not exists, the exception ucltip.CommandNotFound raises

?View Code PYTHON
a=ucltip.SingleCmd('oo')
Traceback (most recent call last):
    File "", line 1, in
    File "ucltip/__init__.py", line 103, in __init__
    raise CommandNotFound()
ucltip.CommandNotFound

if the command be executed falied, the exception ucltip.CommandExecutedFalur raises

here is a example to hanlde error:

?View Code PYTHON
try:
    print ucltip.SingleCmd('ls')
except ucltip.CommandExecutedFalur as e:
    print e

Command Dispatcher

Some command tools has sub command, like `git`, `zenity`, `pbuilder`, `apt-get`, etc.and some commands like `zenity`, they have prefix string in their sub command.

?View Code PYTHON
# the sub command name is the method name
git = CmdDispatcher('git')
git.log()
# and you can also give args and options like what SingleCmd can use
git.log(raw=True, since='2010')
 
# you can get Popen instance also
proc = git.log(interact=True)
 
# zenity has '--' prefix in its sub command, so you need to specify prefix string
# and option style
zenity = CmdDispatcher('zneity', opt_style=1, subcmd_prefix='--')
 
# zneity --info --text=hi
zneity.info(text="hi")

support:

biggo.com.tw

A Django site.