How would I implement something similar to functional programming within bash?
I have a function:
requestPassword(){
passwordValidated=false
while [ "$passwordValidated" = "false" ];do
tput clear
[ -n "$infomsg" ] && echo -e "$infomsg" >&2
[ -n "$errmsg" ] && echo -e "$errmsg" >&2
read -s -p "some prompt:" pass >&2
errmsg=$()#do some validation
[ -n "$errmsg" ] && continue
passwordValidated=true
done
echo "$pass"
}
But I want to make it as generic as possible to work with different systems
Maybe I want to ask the password for an encrypted file Maybe I want to ask the password for a system user Maybe I want to use this function to request a new password from a user
The idea would be that I could pass this function a function that takes in a pass parameter and only outputs something if validation failed
CodePudding user response:
This is my solution. Please feel free to add any more insight you may have on this topic
requestPassword(){
infomsg="$1"
passwordValidated=false
while [ "$passwordValidated" = "false" ];do
tput clear
[ -n "$infomsg" ] && echo -e "$infomsg" >&2
[ -n "$errmsg" ] && echo -e "$errmsg" >&2
read -s -p "some prompt:" pass >&2
errmsg=$(dynPasswordValidation "$pass")
[ -n "$errmsg" ] && continue
passwordValidated=true
done
echo "$pass"
}
You would then have other functions that would call this function for specific password requests but would define dynPasswordValidation function prior to the call like so:
requestCurrentEncryptedFilePassword(){
infomsg="Requesting password for encrypted file"
dynPasswordValidation(){
[ -n "$(openssl $encalg -d -in $encfile -pass "pass:$1" 2>&1>/dev/null)" ] && echo "Looks like that password didn't work" && return
}
pass="$(requestPassword "$infomsg")"
}
requestNewEncryptedFilePassword(){
infomsg="Requesting new password for encrypted file"
dynPasswordValidation(){
pass="$1"
echo >&2
read -p -s "veri prompt" pass_veri >&2
echo >&2
[ "$pass" != "$pass_veri" ] && echo "Looks like the passwords didn't match" && return
[ -n "$(#run the password through a set of password rules)" ] && echo "Looks like the password is not up to snuff..." && return
}
pass="$(requestPassword "$infomsg")"
}
CodePudding user response:
You can pass a function name as an argument
requestPassword(){
local infomsg="$1"
local validator=${2:-the_default_validator_function}
# ...
local errmsg
errmsg=$( "$validator" "$pass" )
# ...
}
then
# a valid "foobar" password contains the substring "foo"
foobarPasswordValidator() { [[ $1 == *foo* ]]; }
pass=$(requestPassword "Enter your FooBar password" foobarPasswordValidator)
If you don't have a default validator, use :
or true
-- they accept arguments, ignore them(1) and return a "success" exit status.
(1) ignored after any parameter expansions have occurred