#!/bin/bash REDIS_HOST=127.0.0.1 REDIS_PORT=6379 CLIENT_VERSION=0.2 function redis_read_str() { typeset REDIS_STR="$@" printf %b "$REDIS_STR" | cut -f2- -d"+" | tr -d '\r' } function redis_read_err() { typeset REDIS_ERR="$@" printf %s "$REDIS_ERR" | cut -f2- -d"-" exit 1 } function redis_read_int() { typeset -i OUT_INT=$(printf %s $1 | tr -d '\:' | tr -d '\r') printf %b "$OUT_INT" } function redis_read_bulk() { typeset -i BYTE_COUNT=$1 typeset -i FILE_DESC=$2 if [[ $BYTE_COUNT -lt 0 ]]; then echo "ERROR: Null or incorrect string size returned." >&2 exec {FILE_DESC}>&- exit 1 fi echo $(dd bs=1 count=$BYTE_COUNT status=noxfer <&$FILE_DESC 2>/dev/null) dd bs=1 count=2 status=noxfer <&$FILE_DESC 1>/dev/null 2>&1 # we are removing the extra character \r } function redis_read() { typeset -i FILE_DESC=$1 if [[ $# -eq 2 ]]; then typeset -i PARAM_COUNT=$2 typeset -i PARAM_CUR=1 fi while read socket_data do typeset first_char=$(printf %b "$socket_data" | head -c1) case $first_char in "+") #echo "This is a simple string." redis_read_str "$socket_data" ;; "-") #echo "This is an error." redis_read_err "$socket_data" ;; ":") #echo "This is an integer." redis_read_int $socket_data ;; "\$") #echo "This is a bulk string." bytecount=$(printf %b "$socket_data" | cut -f2 -d"\$" | tr -d '\r') redis_read_bulk $bytecount $FILE_DESC ;; "*") #echo "This is an array." paramcount=$(printf %b "$socket_data" | cut -f2 -d"*" | tr -d '\r') redis_read $FILE_DESC $paramcount ;; esac if [[ ! -z $PARAM_COUNT ]]; then if [[ $PARAM_CUR -lt $PARAM_COUNT ]]; then ((PARAM_CUR+=1)) continue else break fi else break fi done<&$FILE_DESC } function redis_get_var() { typeset REDIS_VAR="$@" printf %b "*2\r\n\$3\r\nGET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n" } function redis_set_var() { typeset REDIS_VAR="$1" shift typeset REDIS_VAR_VAL="$@" printf %b "*3\r\n\$3\r\nSET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n\$${#REDIS_VAR_VAL}\r\n$REDIS_VAR_VAL\r\n" } function redis_get_array() { typeset REDIS_ARRAY="$1" printf %b "*4\r\n\$6\r\nLRANGE\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n\$1\r\n0\r\n\$2\r\n-1\r\n" } function redis_set_array() { typeset REDIS_ARRAY="$1" typeset -a REDIS_ARRAY_VAL=("${!2}") printf %b "*2\r\n\$3\r\nDEL\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n" for i in "${REDIS_ARRAY_VAL[@]}" do printf %b "*3\r\n\$5\r\nRPUSH\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n\$${#i}\r\n$i\r\n" done } while getopts g:P:H:p:ha opt; do case $opt in p) REDIS_PW=${OPTARG} ;; H) REDIS_HOST=${OPTARG} ;; P) REDIS_PORT=${OPTARG} ;; g) REDIS_GET=${OPTARG} ;; a) REDIS_ARRAY=1 ;; h) echo "" echo "USAGE:" echo " $0 [-a] [-g ] [-p ] [-H ] [-P ]" echo "" exit 1 ;; esac done # # Main thread # exec {FD}<> /dev/tcp/$REDIS_HOST/$REDIS_PORT if [[ ! -z $REDIS_PW ]]; then redis_compose_cmd "AUTH $REDIS_PW" >&$FD fi if [[ ! -z $REDIS_GET ]]; then if [[ $REDIS_ARRAY -eq 1 ]]; then redis_get_array $REDIS_GET >&$FD IFS=$'\n' typeset -a OUTPUT_ARRAY for i in `redis_read $FD` do OUTPUT_ARRAY+=($i) done typeset | grep ^OUTPUT_ARRAY | sed "s/OUTPUT_ARRAY/$REDIS_GET/" else redis_get_var $REDIS_GET >&$FD redis_read $FD fi exec {FD}>&- exit 0 fi # Pipe read while read line do REDIS_TODO=$line if [[ $REDIS_ARRAY -eq 1 ]]; then ARRAY_NAME=$(printf %b "$REDIS_TODO" | cut -f1 -d"=") typeset -a temparray=$(printf %b "$REDIS_TODO" | cut -f2- -d"=") redis_set_array $ARRAY_NAME temparray[@] >&$FD redis_read $FD 1>/dev/null 2>&1 exit 0 fi KEYNAME=$(printf %b "$REDIS_TODO" | cut -f1 -d"=") KEYVALUE=$(printf %b "$REDIS_TODO" | cut -f2- -d"=") redis_set_var $KEYNAME $KEYVALUE >&$FD redis_read $FD 1>/dev/null 2>&1 done < /dev/stdin exec {FD}>&-