#!/usr/bin/env sh # compat: +ash +bash +dash +zsh ### @ confirm ### display a simple yes-or-no prompt and return 0-or-1 respectively. ### ### ``` ### $ confirm && echo yay || echo nay ### Continue? [y/N] y ### yay ### $ confirm && echo yay || echo nay ### Continue? [y/N] n ### nay ### ``` ### ### a real world example: ### ### ``` ### $ g1 && confirm && git commit -a --amend --no-edit ### daf84e3 document a ton of stuff ### Continue? [y/N] y ### [master 92bdf76] document a ton of stuff ### Date: Sun Aug 1 09:27:25 2021 -0700 ### 20 files changed, 406 insertions(+), 29 deletions(-) ### ``` if [ -n "$ZSH_VERSION" ]; then confirm() { [ $# -eq 0 ] || { printf "%s\n" "$0: too many arguments" >&2; return 2; } local c= read -q '?Continue? [y/N] ' c ret=$? echo >/dev/tty return $ret } elif [ -n "$BASH_VERSION" ]; then confirm() { [ $# -eq 0 ] || { printf "%s\n" "$0: too many arguments" >&2; return 2; } local c= read -n1 -p "Continue? [y/N] " c 2>&1 echo [ "$c" = y ] || [ "$c" = Y ] } 1<>/dev/tty <&1 # ensure this interacts with a terminal instead of a pipe else confirm() ( [ $# -eq 0 ] || { printf "%s\n" "$0: too many arguments" >&2; return 2; } old="$(stty -g)" trap 'stty "$old"' INT EXIT printf 'Continue? [y/N] ' stty -icanon c="$(dd ibs=1 count=1 2>/dev/null)" echo [ "$c" = y ] || [ "$c" = Y ] ) 1<>/dev/tty <&1 # ensure this interacts with a terminal instead of a pipe fi [ -n "${preload+-}" ] || confirm "$@"