From e0aac93c3809041e90cdabcbd4a6ab21b97b4cad Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Sat, 25 Sep 2021 00:17:35 -0700 Subject: [PATCH] rewrite confirm and pause to improve compatibility and consistency --- sh/confirm | 40 +++++++++++++++++++++++++++------------- sh/pause | 50 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/sh/confirm b/sh/confirm index 082ca6d..29a4107 100755 --- a/sh/confirm +++ b/sh/confirm @@ -1,8 +1,8 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # YES_ZSH # YES_BASH -# NO_DASH -# NO_ASH +# YES_DASH +# YES_ASH ### @ confirm ### display a simple yes-or-no prompt and return 0-or-1 respectively. @@ -19,7 +19,7 @@ ### a real world example: ### ### ``` -### % g1 && confirm && git commit -a --amend --no-edit +### $ 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 @@ -27,23 +27,37 @@ ### 20 files changed, 406 insertions(+), 29 deletions(-) ### ``` +# known inconsistencies: +# since the fallbacks pipe stderr into stdin, +# this will behave differently between zsh and non-zsh shells: +# ( echo hi | confirm | wc -c ) 2>/dev/null + if [ -n "$ZSH_VERSION" ]; then confirm() { - [ $# -le 0 ] || { printf "%s\n" "$0: too many arguments" >&2; return 1; } + [ $# -le 0 ] || { printf "%s\n" "$0: too many arguments" >&2; return 2; } read -q '?Continue? [y/N] ' ret=$? - echo + echo >/dev/tty return $ret } -else +elif [ -n "$BASH_VERSION" ]; then confirm() { - # specify stdin (1) to avoid taking input from pipes - [ $# -le 0 ] || { printf "%s\n" "$0: too many arguments" >&2; return 1; } - read -n1 -u 1 -p "Continue? [y/N] " c + [ $# -le 0 ] || { printf "%s\n" "$0: too many arguments" >&2; return 2; } + read -n1 -p "Continue? [y/N] " c echo - [ "$c" != 'y' ] && [ "$c" != 'Y' ] && return 1 - return 0 - } + [ "$c" = y ] || [ "$c" = Y ] + } <&2 >/dev/tty # try to ensure this is a terminal instead of a pipe +else + confirm() ( + [ $# -le 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 ] + ) <&2 >/dev/tty # try to ensure this is a terminal instead of a pipe fi [ -n "${preload+-}" ] || confirm "$@" diff --git a/sh/pause b/sh/pause index 8d920e2..3f0c059 100755 --- a/sh/pause +++ b/sh/pause @@ -1,21 +1,39 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # YES_ZSH # YES_BASH -# NO_DASH -# NO_ASH +# YES_DASH +# YES_ASH -pause() { ### @- - ### pause — the companion script of [`confirm`.](#confirm) - ### - ### ``` - ### $ pause - ### Press any key to continue - ### $ - ### ``` - [ -n "${ZSH_VERSION:-}" ] \ - && read -sk '?Press any key to continue -' || read -n1 -u 1 -sp 'Press any key to continue -' -} +### @ pause +### pause — the companion script of [`confirm`.](#confirm) +### +### ``` +### $ pause +### Press any key to continue +### $ +### ``` + +# known inconsistencies: +# since the fallbacks pipe stderr into stdin, +# this will behave differently between zsh and non-zsh shells: +# ( echo hi | pause | wc -c ) 2>/dev/null + +if [ -n "$ZSH_VERSION" ]; then + pause() { + read -sk $'?Press any key to continue\n' + } +elif [ -n "$BASH_VERSION" ]; then + pause() { + read -n1 -sp $'Press any key to continue\n' + } <&2 >/dev/tty # try to ensure this is a terminal instead of a pipe +else + pause() ( + old="$(stty -g)" + trap 'stty "$old"' INT EXIT + printf 'Press any key to continue\n' + stty -icanon -echo + dd ibs=1 count=1 2>/dev/null >/dev/null + ) <&2 >/dev/tty # try to ensure this is a terminal instead of a pipe +fi [ -n "${preload+-}" ] || pause "$@"