I need to write a POSIX shell script that will change system configurations. Before doing so I want to ensure there are backups of any file I edit.
A requirement for this script is that is uses dmenu to prompt the user if installed and read if not.
I want one function (named communicate below) that will automatically handle this for me based on a variable that gets set on run, $dmenu.
I'm having issues writing to a variable inside a variable, as shown below:
#!/usr/bin/env sh
[ $(command -v dmenu 2>/dev/null) ] && dmenu='true'
communicate(){
description="$1"; options="$2"; outcome="$3"
if [ $dmenu ]; then
echo "$(printf "$options" | dmenu -i -p "$description")" >&0 | read $outcome
else
printf "$description $options "; read $outcome
fi
}
backup(){
[ $1 ] && file="$1" || communicate 'Enter file: ' '' 'file'
[ ! -f $file ] && backup "$1"
cp "$file" "$file.bak"
}
select_interface(){
[ $1 ] && interface="$1" || communicate 'Select interface:' "$interfaces" 'interface'
}
backup wants to save user input to a variable called $file, whereas later select_interface wants to save to a variable called $interface.
if dmenu is not installed, writing to $outcome works fine with the else statement, whereas if it is installed, I cannot seem to get the read command to trigger when passing the outcome of dmenu through with the STDIN redirect into read, which works outside of the script.
Can someone see what I'm doing wrong or how I could do this better? I need it all to be in the one function communicate, acting as the communicating agent with the user.