Confirmation prompts for shell scripts

The source code of Arch Linux’s pacman defines a function that prompts the user for confirmation. It handles the answer as follows:

=> Function “question” in src/pacman/util.c

I present different functions that emulate this behavior in POSIX shell.

Default yes

To have yes as the default answer, use this:

confirm_y() {
	local answer
	printf 'Continue? (Y/n) ' >&2
	read answer
	case "$answer" in
	""|Y|y|[Yy][Ee][Ss]) return 0;;
	*) return 1;;
	esac
}

A return value of 0 means true. Anything else means false.

The function doesn’t work if stdin is not the terminal (e.g. when reading from a file). But it does still work if stdout is redirected, as the prompt is printed to stderr instead of stdout.

Default no

To have no as the default answer, use this:

confirm_n() {
	local answer
	printf 'Continue? (y/N) ' >&2
	read answer
	case "$answer" in
	Y|y|[Yy][Ee][Ss]) return 0;;
	""|*) return 1;;
	esac
}

Flexible defaults

To specify a default answer when calling the function, use this:

confirm_d() {
	local options answer
	case "$1" in
	""|Y|y|[Yy][Ee][Ss]) options='(Y/n)';;
	*) options='(y/N)';;
	esac
	printf 'Continue? %s ' "$options" >&2
	read answer
	case "${answer:-$1}" in
	""|Y|y|[Yy][Ee][Ss]) return 0;;
	*) return 1;;
	esac
}

If it reads the empty string, the function replaces it with the default answer. The default answer is handled as in confirm_y. So if no default answer is specified, the function assumes yes.

Custom question and flexible defaults

To also specify a custom question, use this:

confirm_q_d() {
	local options answer
	case "$2" in
	""|Y|y|[Yy][Ee][Ss]) options='(Y/n)';;
	*) options='(y/N)';;
	esac
	printf '%s %s ' "${1:-Continue?}" "$options" >&2
	read answer
	case "${answer:-$2}" in
	""|Y|y|[Yy][Ee][Ss]) return 0;;
	*) return 1;;
	esac
}

If no question is specified, the function assumes “Continue?”.

EOF

Proxy Information
Original URL
gemini://dkalak.de/tech/confirm.gmi
Status Code
Success (20)
Meta
text/gemini; lang=en
Capsule Response Time
155.413597 milliseconds
Gemini-to-HTML Time
0.549723 milliseconds

This content has been proxied by September (3851b).