Advertisement
bash-masters

bashpipe

Oct 26th, 2012
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 3.49 KB | None | 0 0
  1. #!/bin/bash -n
  2.  
  3. [[ $1 =~ ^(-h|--help|-\?)$ ]] && {
  4.  
  5. cat | less <<MANUAL
  6.  
  7. NAME
  8.        bashpipe
  9.  
  10. SYNOPSIS
  11.        bashpipe [options] IDENTIFIER
  12.  
  13. DESCRIPTION
  14.        Creates a pipe with two auto-selected file descriptors and stores,
  15.        information about the pipe into a bash array. The function also,
  16.        creates convenience functions for working with the pipe, and managing
  17.        its lifecycle.
  18.  
  19. OPTIONS
  20.        -p       print information about a bashpipe identifer
  21.        -E       sets function local variable EXTEND
  22.  
  23.        --print  same as -p
  24.  
  25. ENVIRONMENT VARIABLES: EXTEND
  26.  
  27. ENVIRONMENT VARIABLE EXTEND
  28.        This variable, when set, provides the \`dot prefix\` for all
  29.        convenience functions. When this variable is not set,
  30.        IDENTIFIER is the prefix.
  31.  
  32. EXAMPLE
  33.        source bashpipe;
  34.        bashpipe "io"; declare -p io; ls /dev/fd;
  35.        io.write "Hello world"; io.read -u ${io[0]};
  36.        echo $REPLY; io.close;
  37.        declare -p io; ls /dev/fd;
  38.  
  39.        The above example performs a write to the pipe input, and reads from,
  40.        the same descriptor using the convenience function assigned to the
  41.        output descriptor.
  42.  
  43. AUTHOR
  44.        Written by Triston J. Taylor.
  45.  
  46. REPORTING BUGS
  47.        Report bashpipe bugs to pc.wiz.tt@gmail.com
  48.        bash-masters home page: <https://www.facebook.com/alt.bash>
  49.        bash-masters pastebin: <http://pastebin.com/u/bash-masters>
  50.  
  51. COPYRIGHT
  52.        Copyright © 2012 Triston J. Taylor - bash-masters
  53.        License: GPLV3; <http://gnu.org/licenses/gpl.html>
  54.  
  55. MANUAL
  56.  
  57. return;
  58.  
  59. }
  60.  
  61. [[ $BASH_VERSION < 4.2 ]] && {
  62.     echo error: module \`bashpipe\' requires bash 4.2 or newer >&2;
  63.     return 1;
  64. }
  65.  
  66. [[ -d /tmp ]] || {
  67.     echo bashpipe: error: cannot find /tmp directory
  68.     return 1;
  69. }
  70.  
  71. function bashpipe() {
  72.  
  73.     while [[ ${1:0:1} = - ]]; do
  74.         [[ $1 =~ ^(-p|--print)$ ]] && {
  75.             local in=$2[0] out=$2[1];
  76.             [[ -z ${!in} ]] && {
  77.                 echo bashpipe: error: print: invalid identifier >&2;
  78.                 return 1;
  79.             }
  80.             echo "/dev/fd/${!in} /dev/fd/${!out}";
  81.             return;
  82.         };
  83.         [[ $1 == '-E' ]] && {
  84.             local EXTEND=$2; shift 2; continue;
  85.         }
  86.         echo bashpipe: error: unidentified option: \`$1\' >&2; return 1;
  87.     done;
  88.  
  89.     (( $# != 1 )) && {
  90.         echo bashpipe: error: invalid arguments;
  91.         return 1;
  92.     } >&2;
  93.  
  94.     local ID=$1;
  95.  
  96.     declare -p $ID 2>&- > /dev/null && {
  97.         local in=$ID[0] out=$ID[1];
  98.         [[ -e /dev/fd/${!in} && -e /dev/fd/${!out} ]] && {
  99.             echo bashpipe: error: \`$ID\' appears to be a valid bashpipe;
  100.             return 1;
  101.         } >&2;
  102.     }
  103.  
  104.     local -i FD=${FD:-69}; # start from env. / foxbridge callback
  105.  
  106.     local -i pFDIn=$(
  107.         while [[ -e /dev/fd/$(( ++FD )) ]]; do :; done; echo -n $FD
  108.     );
  109.  
  110.     local -i pFDOut=$(
  111.         FD=$pFDIn;
  112.         while [[ -e /dev/fd/$(( ++FD )) ]]; do :; done; echo -n $FD
  113.     );
  114.  
  115.     local bashpipe=/tmp/$$.bashpipe; local -i v=2;
  116.  
  117.     [[ -e $bashpipe.sh ]] && {
  118.         while [[ -e /tmp/$bashpipe.$v.sh ]]; do (( v++ )); done
  119.         bashpipe+=.$v;
  120.     }
  121.  
  122.     bashpipe+=.sh;
  123.  
  124.     local EXTEND=${EXTEND:-$ID};
  125.  
  126. local subscript=$(echo "declare -ag $ID[0]=$pFDIn $ID[1]=$pFDOut; # record endpoints
  127. exec $pFDIn<> <(:) $pFDOut<> <(:); # open endpoints
  128.  
  129. function $EXTEND.write() {
  130.     (( \$# > 0 )) && {
  131.         echo \"\$@\" > '/dev/fd/$pFDIn'
  132.     } || cat > '/dev/fd/$pFDIn';
  133. }
  134. function $EXTEND.read() {
  135.     read \"\$@\" < /dev/fd/$pFDOut;
  136. }
  137. function $EXTEND.close() {
  138.     exec ${pFDIn}>&- ${pFDOut}>&-;
  139.     unset -f $EXTEND.close $EXTEND.read $EXTEND.write; unset $ID; rm '$bashpipe'
  140. }"
  141. );
  142.  
  143.     echo "$subscript" > "$bashpipe";
  144.     source "$bashpipe";
  145.  
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement