Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Saturday, February 11, 2012

Mixed language (bash/python) function to deal with stdin pipes

often i find the need to be able to use one of my bash scripts to process data from a stdin pipe like:

somecommand |myscript


the standard way is to 'cat /dev/stdin' but alone doesnt do what is needed. for instance perhaps you are not piping output to the script (however this is simple to deal with as an 'if ! [ -t 0 ] ' statement). sometimes options/argument can get mixed into the pipe. the standard solution is to read (ie: 'cat /dev/stdin') using a non-breaking(/blocking, i forget) stty, but this kind of reading of stdin is tricky, and confusing, and /dev/stdin may not be available in all systems (chrooted hosting accounts for instance).

a simple solution is to create a bash function calling python (most systems that include bash also include python) to read stdin, and write directly back to stdout (in essence a simple python pager called as a bash function). this function looks like:

getstdin (){
python -c "from sys import *
if not stdin.isatty():stdout.write(stdin.read())
else:exit(1)"
}


note: ';else:exit(1)' isnt strictly required, but gives a standard error code if nothing on the stdin pipe, which is useful to further script logic (determining the error codes of commands to decide what functionality to produce)

this function takes care of the previously mentioned method's pitfalls. include this function in your own bash script, and deal with (or ignore) stdin pipe easily. a simple example bash script using this function:

#!/bin/bash
#  mystdin.sh
#  by - nairb <c0d3@nairb.us>
#  purpose: to add the text "RECIEVED: " and return stdin pipe

getstdin (){
python -c "from sys import *
if not stdin.isatty():stdout.write(stdin.read())
else:exit(1)"
}

stdin=$(getstdin)
if [ $stdin ];then
  echo "RECEIVED: $stdin"
else
  echo "didnt get anything on stdin, doing something else"
fi


you could run the above example script with a command like:

echo "this is some text" | bash mystdin.sh


the above function is also an example of the standard way to read from a stdin pipe in python scripts (not just calling python in bash).

--
hope someone finds this post useful,
- nairb

Monday, July 25, 2011

Python Superscript

similar to my last post about bash scripting with "basename" functionality, here is an example python module to determine the name of the link being called as well as the arguments supplied:


#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""
        PROJECT - MODULE:
                Python-SuperScript.py

        DESCRIPTION:
                example basename functionality handling in python

        @copyright: 2011 by nairb <code@nairb.us>
        @license: GNU GPL, see COPYING for details.
"""

import os, sys, string

class App(object):
        """ Class doc """
     
        def __init__ (self):
                """ Class initialiser """
                pass
             
        def progName(self):
                """  Return the program name of running script
                @param: none
                @return: base name of the running script
                """
                argvz=string.split(sys.argv[0], '/')
                return argvz[len(argvz)-1]
             
        def progArgs(self):
                """ Return the array of arguments given
                @param: none
                @return: the arguments passed to script
                """
                return sys.argv[1:]

        def Main(self):
                """ Main Function
                @param PARAM:
                @return RETURN:
                """
                print "This program was called as:\n\t" + str(self.progName()) + "\n\nArguments where passed of:\n\t" + str(self.progArgs())
     
if __name__ == '__main__':
    a=App()
    a.Main()

hope someone finds this useful