However, while running the code - with regular (expected numeric input)... it becomes this:
++ builtin echo 6
++ grep -q '^\[\['
++ continue
Which definitly is NOT what I had expected as behaviour.
Any ideas why I get this 'false positive'?
Thank you in advance
EDIT:
It is even worse / more weird...
# Catch invalid inputs
set -x
# Keep reading if NUM is empty
[[ -z "$NUM" ]] && continue
# Also keep reading if NUM length = 0 ; is this even required?
[[ ${#NUM} -eq 0 ]] && continue
# Keep reading if NUM contains letters
# Using builtin echo for speed and less disk usage
builtin echo "$NUM" | $GREP -q [a-zA-Z] && continue # &2>/dev/zero
# Check for arrow keys
builtin echo "$NUM" | $GREP -q '^\[\[' && continue
Still fails.
It passes [a-zA-Z] (double & single quotes) just to fail at the '^\[\[' line AFTERwards....
But either way, the "++debug output showed single quotes in the first post, despite not having them.
AHHHHHHHHHHHHHHHHH SCREW IT....
Closed terminal... started a new one and now....
No colors/borders anymore... FFFFFF=white of anger....
Bet the issue was somewhere there (in the env-memory of said now-closed terminal window-tab).....
All my (obviously imagined) fixes.. worthless... once more... again....
I'm back to square one... to fix the display-functions that i THOUGHT were working yesterday evening.. 24 hrs ago... WTF?!?!
No more coding today...
I do remember you being quite concerned with performance in this SWARM stuff and I would have thought the bash =~ operator could be use in place of grep.
$ export NUM='[['
$ time bash -c 'echo "$NUM" | grep -q "^\[\[" && echo yes'
yes
real 0m0.200s
user 0m0.000s
sys 0m0.107s
$ time bash -c '[[ "$NUM" =~ ^\[\[ ]] && echo yes'
yes
real 0m0.099s
user 0m0.015s
sys 0m0.046s
Twice as fast on my system, but your mileage may vary
But it's working now, thank you MIG & Rav, though, mostly because I droped 'those' catches alltogether...
Here's the full working pick :
pick() { # [-1 -2 -a -m] $LIST or ${ARRAYS[@]}
# Select an item of a LIST or an ARRAY
# Returns the value
#
# Variables
#
local counter=0
local AUTO=false
local ROWS="3"
local as_menu=false
#
# Catch arguments
#
for opt in "${@}"
do if [[ "-" == "${opt:0:1}" ]]
then case "${opt/-}" in
1|2|3) ROWS="${opt/-}"
shift
;;
"a") AUTO=true
shift
;;
"m") trap "return 130" INT ABRT KILL
as_menu=true
shift
;;
"-") wasPipe=true
;;
esac
fi
done
# Can not be set earlier because of possible options
# Which state wether it is 'as menu' or default
$as_menu && \
local ARGS=( "${SWARM_MSG_PICK_BACK}" "${@}" ) || \
local ARGS=("${@}")
#
# Pipe handling
# It's different when working with 'read'
#
#wasPipe=false
#[ -z "$1" ] && \
# while IFS= read -r ARG
# do set -- "$@" "$ARG" && wasPipe=true
# done
# Handle auto-pick (only 1 option)
"$AUTO" && \
[ "$#" -eq 1 ] && \
$PRINTF '%s\n' "$ARGS" >&1 && \
return 4
# Show the items to pick from
#set +x
$as_menu && \
printlist -n -$ROWS -0 ${ARGS[@]} || \
printlist -n -$ROWS "${ARGS[@]}"
#set -x
# Set dynamic values
# Amount of arguments
local pick_count=${#ARGS[@]}
# Character length of the amount
local pick_len=${#pick_count}
#Special handling
local invalid=true
local NUM=""
local POS="$(swarm.print.goto $(( $identRight + 2 )))${SWARM_THEME_DATA[read]} "
$as_menu && \
local min=0 || \
local min=1
#
# Visuals
#
while $invalid
do
# Except the best, prepare for the worst
#invalid=false
# Print the input line:
swarm.print.border
$PRINTF "$POS $POS" >&2
# Read the input
builtin read -n $pick_len NUM
# Catch invalid inputs
# Keep reading if NUM is empty
[[ -z "$NUM" ]] && continue
# Check if NUM is numeric
if [[ ${#NUM} -ge 0 ]] &2>/dev/zero
then
# If it's exactly 0, it's BACK
[[ ${#NUM} -eq 0 ]] && $ECHO "${ARGS[$NUM]}" && return
# It's not zero but some other numeric input
# Keep reading if it is not greater than 'min'-imum
[[ ${NUM} -ge $min ]] &2>/dev/zero || continue
# Keep reading if it is greater than pick_count
[[ $NUM -gt $pick_count ]] && continue
# Exit the loop
invalid=false
else
# It's not a number, catch other cases
continue
# Actualy, all checks below are (can be) left out....
# Keep reading if NUM contains letters
# Using builtin echo for speed and less disk usage
builtin echo "$NUM" | $GREP -E -q "[a-zA-Z]" && continue # &2>/dev/zero
# Check for arrow keys
#builtin echo "$NUM" | $GREP -E -q "^\[\[" && continue
[[ "$NUM" =~ '^[[' ]] && continue
# Keep reading if NUM is longer than $pick_len
# ?? This SHOULD catch arrow-keys in most real usage cases
[[ ${#NUM} -gt ${pick_len} ]] &2>/dev/zero && continue
fi
done
# Make 'nice to have' line break when read automatically stops reading
if [ "${#NUM}" -eq "${#len}" ]
then # Only print newline character if the entered number as the longest number
# But not sub zero
[ "${NUM}" -ne -1 ] && $PRINTF "\n" >&2
else # Since arrays are 0 indexed, 10 becomes 9 and need special treatment
[ "${NUM}" -eq 9 ] && $PRINTF "\n" >&2
fi
$as_menu || NUM=$(( $NUM - 1))
# Prepare output
$ECHO "${ARGS[$NUM]}"
unset opt
}
Yes, I'm always getting confused whether to use /dev/null or /dev/zero, because most of the *nix flavors I use, have both.
if [[ ${#NUM} -ge 0 ]] &2>/dev/null
Yes, this might be unususal, but it helps to avoid parsing errors -> well the visual breakup <- when 'catching' arrow keys (NOT specificly).
Are you refering to the other '^[[' line just above - which is commented out, or to the '[a-zA-Z]' grep to be changed to ~= ?
But basicly, neither of those lines are 'now' executed, because it's 'all' left out anyway - to my understanding - the only reason it's still there, is because I just had it rewritten it compared to the initial post (before sleeping).
else
# It's not a number, catch other cases
continue
# Actualy, all checks below are (can be) left out....
&2>/dev/null is still odd, the & is too many. The & before a descriptor number is needed on the RHS only, to distinguish it from a file name.
And, the only errors that a [[ ]] can produce are "syntax error", "not an integer", "division by zero". You want to see them!
If you want to supress an error from an embedded sub shell expression than redirect it within the sub shell.
In general, only suppress error messages when it makes sense - they help you!
Thank you, I'll try to keep that present (2 & null) after reviewing current code.
What is this RHS you are refering to please?
Uhm, not really on the possible error topic - as I experienced it differently.
....
Phew... i still had that in the terminal so I could scroll to it...
This is with code of the 'initial' post/s ; where the 'catch' was different from the code we're talking about now (recent post with code).
This 'symbol' cannot be compared to a number, thus creating an 'expected' error message, which I wanted to get rid of -> as it breaks the visual experience.
Could you advice a better handling for this situation?
-> Catching arrow keys without showing the enduser an error message? <-
Where I would have expected a continue before the ++set +x ...
My point beeing, sadly, that even with the suggest speed-increase changes, it fails with an error message to the user.
EDIT:
And you were right... (I know wasnt what you wanted to point out):
if [[ ${#NUM} -ge 0 ]] >/dev/null
Is what now solves my expections.
I really wish that those checks would have work/ed out as expected/anticpated, but none did, nor does.
So, I'm left with what is working (gives the expected result), allthough not nice.
EDIT2:
Nevermind.. I tested wrong (forgot to actualy press an arrow key on the X'th 'last' run)...
It's still all messed up when pressing an arrow key....
Yes, I'm always getting confused whether to use /dev/null or /dev/zero, because most of the *nix flavors I use, have both.
As well they should, but they're different. /dev/zero produces zeroes. If you don't need a bunch of zeroes - and who does? - don't use it. null is an esoteric term for nothing, so when you need a device which does nothing - which, despite all odds, is constantly useful - that's null.