Bithon: Run Python Interactively Inside Bash

cat > bithon.sh << EOF
# This script allows python to run as child of bash
# attached to anonymous pipes and all commands in
# bash starting py are sent to python.
 
function launch_python {
  # Close any existing use of these fds.
  exec 3>&-
  exec 4<&-
  pyin=$(mktemp -u)
  pyot=$(mktemp -u)
  mkfifo $pyin
  mkfifo $pyot
  python -u -i <$pyin &>$pyot &
  pypid=$!
  exec 3> $pyin
  exec 4< $pyot

  # Make the pipes 'anonymous'.
  rm $pyin
  rm $pyot
  echo print >&3
  while read -u 4 line
  do
    if [ "${line}" == '>>>' ]
    then
      break
    fi
    echo  "# ${line}"
  done
  echo 'import sys;sys.ps2=""' >&3
}

function py_read {
  local line
  while read -u 4 line
  do
    if [ "${line}" == '.' ]
    then
      break
    fi
    if [ "${line}" != '>>>' ]
    then
       line="${line#>>> }"
       if [ "${line}" != '>>>' ]
       then
          echo "${line#>>>}"
       fi
    fi
  done
}

function py {
  ( (echo "$@" >&3; echo "print '\n.'" >&3)& )
  py_read
}

function _ppy {
  local line
  IFS=''
  while read line
  do
    echo "$line" >&3
  done
  echo >&3
  echo 'print "\n."' >&3
}

function ppy {
  ( _ppy <&0 & )
  py_read
}


function kill_python {
  exec 4<&-
  exec 3>&-
  kill -9 $pypid
}
EOF


...

. ./bithon.sh; launch_python
[3]+  Done                    python -u -i < $pyin >&$pyot
[3] 19375
# Python 2.7.10 (default, Feb  7 2017, 00:08:15)
# [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
# Type "help", "copyright", "credits" or "license" for more information.
bash-3.2$ py import sys
bash-3.2$ v=$(py sys.version)
bash-3.2$ echo $v
'2.7.10 (default, Feb 7 2017, 00:08:15) n[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]'


...

# Create a list in python using a loop and iterate over it in bash.
# Which is using floating point numbers which you cannot use in bash directly.

bash-3.2$ for x in $(ppy << EOF
for x in xrange(10):
    print x*x / 0.123
EOF
); do echo $x; done
0.0
8.13008130081
32.5203252033
73.1707317073
130.081300813
203.25203252
292.682926829
398.37398374
520.325203252
658.536585366


...

# Add two floating point numbers.

bash-3.2$ res=$(py 1.234 + 34.2)
bash-3.2$ echo $res
35.434000000000005


...

# Use numpy to get the media length in lines of all the java files
# in the Sonic Field project.

bash-3.2$ py import numpy
bash-3.2$ counts=$(find ~/SonicFieldRepo/SonicField/ | grep java | xargs wc | awk '{print $1}' | tr '\n' ',')
bash-3.2$ py "numpy.median([$counts])"

46.0

# Which I think is pretty cool!

Comments

Post a Comment

Popular posts from this blog

oche, lik echo but a bit easier to use.

Parsing Columns From Files WITHOUT awk