doorbuzz/redi.sh

199 lines
4.3 KiB
Bash
Executable File

#!/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 <var>] [-p <password>] [-H <hostname>] [-P <port>]"
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}>&-