diff --git a/README.md b/README.md index af1c6d3..ed73190 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,18 @@ Redi.sh is a primitive Redis client, written entirely in Bash. It allows you to > By default redi.sh reads input from stdin and interprets it as a variable or array (if -a is used). To avoid setting redis hostname and port number with each command, you can export REDIS_HOST and REDIS_PORT variables. ``` -./redi.sh [-a] [-g ] [-p ] [-H ] [-P ] +./redi.sh [-a] [-w] [-g ] [-p ] [-H ] [-P ] -a : Tells the script that we are working with arrays, instead of regular variables. + -w : Input as raw instead of read line by line, don't replace "\n" as 0x0a. -r : When used with -a, defines the range of elements to get from the array. Default is all (0,-1). -g : Get the variable/array specified by and output it to stdout. - -s : Set the variable/array specified by with the input from stdin. + -s : Set the variable/array specified by with the input from stdin. + -S : RPUSH command. This also set -a -s. + -G : BLPOP command, the timeout is 0. This also set -g, overrides -a, they are mutually exclusive. -p : Use "AUTH " before running the SET/GET command to authenticate to redis. -H : Specify a custom hostname to connect to. Default is localhost. - -d : Specify a custom database number from range 0-15\. Default is 0 + -d : Specify a custom database number from range 0-15\. Default is 0 -P : Specify a custom port to connect to. Default is 6379. ``` @@ -35,6 +38,24 @@ green blue ``` +```shell +$ echo yellow | ./redi.sh -as queue +$ ./redi.sh -ag queue +yellow +$ echo red green blue | ./redi.sh -S queue +$ ./redi.sh -ag queue +yellow +red +green +blue +``` + +```shell +$ ./redi.sh -G queue +queue +yellow +``` + ## License MIT diff --git a/redi.sh b/redi.sh index 5798506..f10ae53 100755 --- a/redi.sh +++ b/redi.sh @@ -32,7 +32,7 @@ function redis_read_bulk() { exit 1 fi - echo $(dd bs=1 count=$BYTE_COUNT status=noxfer <&$FILE_DESC 2>/dev/null) + dd bs=1 count=$BYTE_COUNT status=noxfer of=/dev/stdout <&$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 } @@ -73,6 +73,7 @@ do if [[ ! -z $PARAM_COUNT ]]; then if [[ $PARAM_CUR -lt $PARAM_COUNT ]]; then ((PARAM_CUR+=1)) + echo continue else break @@ -97,15 +98,57 @@ function redis_select_db() { 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" + if [ -z $REDIS_HASH ]; then + typeset REDIS_VAR="$@" + printf %b "*2\r\n\$3\r\nGET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n" + else + typeset REDIS_VAR="$1" + typeset REDIS_FIELD=$REDIS_HASH + printf %b "*3\r\n\$4\r\nHGET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n\$${#REDIS_FIELD}\r\n${REDIS_FIELD}\r\n" + fi +} + +function redis_blpop_var() { + ((number=$#+1)) + protocol="*$number\r\n\$5\r\nBLPOP\r\n" + for i in "$@"; do + protocol="$protocol\$${#i}\r\n$i\r\n" + done + printf %b $protocol } 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" + if [ -z $INPUT_RAW ]; then + 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" + else + printf %b "*3\r\n\$3\r\nSET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n\$${#REDIS_VAR_VAL}\r\n" + echo -n "$REDIS_VAR_VAL" + printf %b "\r\n" + fi +} + +function redis_hset_var() { + typeset REDIS_VAR="$1" + typeset REDIS_FIELD="$2" + typeset REDIS_VALUE="$3" + typeset BYTES=`echo -n ${REDIS_VALUE} | wc -c` + printf %b "*4\r\n\$4\r\nHSET\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n\$${#REDIS_FIELD}\r\n${REDIS_FIELD}\r\n\$${BYTES}\r\n${REDIS_VALUE}\r\n" +} + +function redis_del_var() { + typeset REDIS_VAR="$1" + printf %b "*2\r\n\$3\r\nDEL\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n" +} + +function redis_hincrby() { + typeset REDIS_VAR="$1" + typeset REDIS_FIELD="$2" + typeset REDIS_VALUE="$3" + typeset BYTES=`echo -n ${REDIS_VALUE} | wc -c` + printf %b "*4\r\n\$7\r\nHINCRBY\r\n\$${#REDIS_VAR}\r\n$REDIS_VAR\r\n\$${#REDIS_FIELD}\r\n${REDIS_FIELD}\r\n\$${BYTES}\r\n${REDIS_VALUE}\r\n" } function redis_get_array() { @@ -118,15 +161,24 @@ function redis_get_array() { function redis_set_array() { typeset REDIS_ARRAY="$1" typeset -a REDIS_ARRAY_VAL=("${!2}") + typeset REDIS_RAW_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 + if [ -z $REDIS_PUSH ]; then + printf %b "*2\r\n\$3\r\nDEL\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n" + fi + if [ -z $INPUT_RAW ]; then + 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 + else + printf %b "*3\r\n\$5\r\nRPUSH\r\n\$${#REDIS_ARRAY}\r\n$REDIS_ARRAY\r\n\$${#REDIS_RAW_VAL}\r\n" + echo -n "$REDIS_RAW_VAL" + printf %b "\r\n" + fi } -while getopts g:s:r:P:H:p:d:ha opt; do +while getopts g:s:r:P:H:p:d:G:S:D:I:f:haw opt; do case $opt in p) REDIS_PW=${OPTARG} @@ -143,27 +195,51 @@ while getopts g:s:r:P:H:p:d:ha opt; do a) REDIS_ARRAY=1 ;; + w) + INPUT_RAW=1 + ;; r) REDIS_ARRAY_RANGE=${OPTARG} ;; s) REDIS_SET=${OPTARG} ;; + G) + REDIS_ARRAY=0 + REDIS_POP=1 + REDIS_GET=${OPTARG} + ;; + S) + REDIS_ARRAY=1 + REDIS_PUSH=1 + REDIS_SET=${OPTARG} + ;; + D) + REDIS_DEL=${OPTARG} + ;; + I) + REDIS_HINCRBY=$2 + REDIS_HINCRBY_FIELD=$3 + REDIS_HINCRBY_VALUE=$4 + ;; + f) + REDIS_HASH=${OPTARG} + ;; d) REDIS_DB=${OPTARG} ;; h) echo echo USAGE: - echo " $0 [-a] [-r ] [-s ] [-g ] [-p ] [-d ] [-H ] [-P ]" + echo " $0 [-a] [-w] [-r ] [-s ] [-g ] [-S ] [-G ] [-p ] [-d ] [-H ] [-P ] [-D ] [-I ]" echo exit 1 ;; esac done -if [[ -z $REDIS_GET ]] && [[ -z $REDIS_SET ]]; then - echo "You must either GET(-g) or SET(-s)" >&2 +if [[ -z $REDIS_HINCRBY ]] && [[ -z $REDIS_DEL ]] && [[ -z $REDIS_GET ]] && [[ -z $REDIS_SET ]]; then + echo "You must either DEL(-D) or HINCRBY(-I) or GET(-g) or SET(-s) or BLPOP(-G) or RPUSH(-S)" >&2 exit 1 fi @@ -187,6 +263,10 @@ if [[ ! -z $REDIS_GET ]]; then echo $i done + elif [ ! -z $REDIS_POP ]; then + redis_blpop_var "$REDIS_GET" 0 >&$FD + redis_read $FD + else redis_get_var "$REDIS_GET" >&$FD redis_read $FD @@ -196,21 +276,44 @@ if [[ ! -z $REDIS_GET ]]; then exit 0 fi -while read -r line -do - REDIS_TODO=$line -done &$FD + redis_read $FD + exec {FD}>&- + exit 0 +fi + +if [[ ! -z $REDIS_HINCRBY ]]; then + redis_hincrby "$REDIS_HINCRBY" "$REDIS_HINCRBY_FIELD" "$REDIS_HINCRBY_VALUE" >&$FD + redis_read $FD + exec {FD}>&- + exit 0 +fi + +if [[ -z $INPUT_RAW ]]; then + while read -r line + do + REDIS_TODO=$line + done &$FD - redis_read $FD 1>/dev/null 2>&1 + if [[ -z $INPUT_RAW ]]; then + set -- $REDIS_TODO + typeset -a temparray=( $@ ) + redis_set_array "$REDIS_SET" temparray[@] >&$FD + else + redis_set_array "$REDIS_SET" "$REDIS_TODO" >&$FD + fi + elif [[ ! -z $REDIS_HASH ]]; then + redis_hset_var "$REDIS_SET" "$REDIS_HASH" "$REDIS_TODO" >&$FD else redis_set_var "$REDIS_SET" "$REDIS_TODO" >&$FD - redis_read $FD 1>/dev/null 2>&1 fi + redis_read $FD 1>/dev/null 2>&1 exec {FD}>&- exit 0 fi