# readlineSync # https://github.com/anseki/readline-sync # # Copyright (c) 2015 anseki # Licensed under the MIT license. # getopt(s) while [ $# -ge 1 ]; do arg="$(printf '%s' "$1" | grep -E '^-+[^-]+$' | tr '[A-Z]' '[a-z]' | tr -d '-')" case "$arg" in 'display') shift; options_display="$1";; 'keyin') options_keyIn=true;; 'noechoback') options_noEchoBack=true;; 'mask') shift; options_mask="$1";; 'limit') shift; options_limit="$1";; 'cs') options_cs=true;; 'encoded') options_encoded=true;; esac shift done reset_tty() { if [ -n "$save_tty" ]; then stty --file=/dev/tty "$save_tty" 2>/dev/null || \ stty -F /dev/tty "$save_tty" 2>/dev/null || \ stty -f /dev/tty "$save_tty" || exit $? fi } trap 'reset_tty' EXIT save_tty="$(stty --file=/dev/tty -g 2>/dev/null || stty -F /dev/tty -g 2>/dev/null || stty -f /dev/tty -g || exit $?)" write_tty() { # 2nd arg: enable escape sequence if [ "$2" = true ]; then printf '%b' "$1" >/dev/tty else printf '%s' "$1" >/dev/tty fi } replace_allchars() { ( text='' for i in $(seq 1 ${#1}) do text="$text$2" done printf '%s' "$text" ) } [ -z "$options_display" ] && [ "$options_keyIn" = true ] && \ [ "$options_noEchoBack" = true ] && [ -z "$options_mask" ] && silent=true [ "$options_noEchoBack" != true ] && [ "$options_keyIn" != true ] && is_cooked=true if [ -n "$options_display" ]; then write_tty "$options_display" fi if [ "$is_cooked" = true ]; then stty --file=/dev/tty cooked 2>/dev/null || \ stty -F /dev/tty cooked 2>/dev/null || \ stty -f /dev/tty cooked || exit $? else stty --file=/dev/tty raw -echo 2>/dev/null || \ stty -F /dev/tty raw -echo 2>/dev/null || \ stty -f /dev/tty raw -echo || exit $? fi [ "$options_keyIn" = true ] && req_size=1 if [ "$options_keyIn" = true ] && [ -n "$options_limit" ]; then if [ "$options_cs" = true ]; then limit_ptn="$options_limit" else # Safe list limit_ptn="$(printf '%s' "$options_limit" | sed 's/\([a-z]\)/\L\1\U\1/ig')" fi fi while : do if [ "$is_cooked" != true ]; then chunk="$(dd if=/dev/tty bs=1 count=1 2>/dev/null)" else IFS= read -r chunk