|
#!/usr/bin/env bash |
|
# |
|
# getpw.bash - GET PassWord |
|
# Copyright (c) 2018-2025 Koichi OKADA. All right reserved. |
|
# This script distributed under the MIT license. |
|
# |
|
|
|
function __getpw_usage () # [<NAME>] |
|
# Generate usage from comment. |
|
#Args: |
|
# <NAME> |
|
# The name of the function to generate usage. |
|
# Default: XXXXX (part of this function name like __XXXXX_usage). |
|
{ |
|
local NAME="${1:-$(sed -E 's/__(\S*)_usage/\1/g' <<<"$FUNCNAME")}" |
|
local SOURCE |
|
for SOURCE in "${BASH_SOURCE[@]}" ""; do |
|
grep -E "^function\\s*($NAME)\\s*\\(\\)\\s*#\\s*(.*)" "$SOURCE" >&/dev/null && break |
|
done |
|
[ -z "$SOURCE" ] && return |
|
|
|
gawk -vNAME="$NAME" ${AWK:+}' |
|
phase == 1 { |
|
if (match($0,"^#(.*)",m)) { |
|
lines[n++] = m[1]; |
|
} else { |
|
phase = 2; |
|
} |
|
} |
|
phase == 0 && match($0,"^function\\s*("NAME")\\s*\\(\\)\\s*#\\s*(.*)",m) { |
|
lines[n++] = "Usage: "m[1](m[2]==""?"":" "m[2]); |
|
phase = 1; |
|
} |
|
END { |
|
for (i in lines) { |
|
print lines[i]; |
|
} |
|
} |
|
' "$SOURCE" |
|
|
|
gawk -vNAME="$NAME" ${AWK:+}' |
|
phase == 2 { |
|
if (match($0, "^\\s*#(.*)",m)) { |
|
lines[n++] = m[1]; |
|
} else { |
|
phase = 1; |
|
} |
|
} |
|
phase == 1 && match($0,"^\\s*(\\S+)\\)\\s*#\\s*(.*)",m) { |
|
lines[n++] = gensub("\\|", ", ", "g", m[1])(m[2]==""?"":" "m[2]); |
|
phase = 2; |
|
} |
|
phase == 0 && match($0,"^function\\s*__"NAME"_optparse\\s*\\(\\)",m) { |
|
phase = 1; |
|
} |
|
0 < phase && match($0, "^}") { |
|
phase = 0; |
|
} |
|
END { |
|
if (n) print "Options:" |
|
for (i in lines) { |
|
print " "lines[i]; |
|
} |
|
} |
|
' "$SOURCE" |
|
} |
|
|
|
function __getpw_optparse () # [<ARGS> ...] |
|
{ |
|
while (( 0 < $#)); do |
|
case "$1" in |
|
-h|--help)# |
|
# show this help. |
|
OPTS["help"]="$1" |
|
shift |
|
;; |
|
-n)# |
|
# do not append a newline. |
|
OPTS["n"]="$1" |
|
shift |
|
;; |
|
--) |
|
shift |
|
ARGS+=( "$@" ) |
|
shift $# |
|
;; |
|
-*) |
|
printf "\e[31;1mError:\e[0m Unknown option: %s\n" "$1" |
|
return 2 |
|
;; |
|
*) |
|
ARGS+=( "$@" ) |
|
shift |
|
;; |
|
esac |
|
done |
|
} |
|
|
|
function getpw () # [OPTIONS] [PROMPT] |
|
# Get password with masked echo back. |
|
{ |
|
local -a ARGS |
|
local -Ag OPTS |
|
__getpw_optparse "$@" || return |
|
[ -n "${OPTS["help"]}" ] && { __getpw_usage; return; } |
|
|
|
local prompt="${ARGS[0]:-Password: }" |
|
local password="" |
|
local ch |
|
while IFS="" read -p "$prompt" -rsn1 ch; do |
|
case "$ch" in |
|
"") |
|
break |
|
;; |
|
$'\x15') |
|
prompt="${password//?/$'\b \b'}" |
|
password="" |
|
;; |
|
$'\x08'|$'\x7f') |
|
[ -n "$password" ] && prompt=$'\b \b' || prompt="" |
|
password="${password%?}" |
|
;; |
|
*) |
|
prompt="*" |
|
password+="$ch" |
|
;; |
|
esac |
|
done |
|
echo >/dev/tty |
|
|
|
echo ${OPTS["n"]:+"${OPTS["n"]}" }"$password" |
|
} |
|
|
|
[ "$(readlink -f -- "$0")" = "$(readlink -f -- "$BASH_SOURCE")" ] && getpw "$@" |