#!/usr/bin/env bash ############################################################################### # # demo-magic.sh # # Copyright (c) 2015 Paxton Hare # # This script lets you script demos in bash. It runs through your demo script when you press # ENTER. It simulates typing and runs commands. # ############################################################################### # the speed to "type" the text TYPE_SPEED=20 # no wait after "p" or "pe" NO_WAIT=false # if > 0, will pause for this amount of seconds before automatically proceeding with any p or pe PROMPT_TIMEOUT=0 # don't show command number unless user specifies it SHOW_CMD_NUMS=false EXEC_WAIT=1 # handy color vars for pretty prompts BLACK="\033[0;30m" BLUE="\033[0;34m" GREEN="\033[0;32m" GREY="\033[0;90m" CYAN="\033[0;36m" RED="\033[0;31m" PURPLE="\033[0;35m" BROWN="\033[0;33m" WHITE="\033[1;37m" COLOR_RESET="\033[0m" C_NUM=0 # prompt and command color which can be overriden DEMO_PROMPT="$ " DEMO_CMD_COLOR=$WHITE DEMO_COMMENT_COLOR=$GREY ## # prints the script usage ## function usage() { echo -e "" echo -e "Usage: $0 [options]" echo -e "" echo -e "\tWhere options is one or more of:" echo -e "\t-h\tPrints Help text" echo -e "\t-d\tDebug mode. Disables simulated typing" echo -e "\t-n\tNo wait" echo -e "\t-w\tWaits max the given amount of seconds before proceeding with demo (e.g. '-w5')" echo -e "" } ## # wait for user to press ENTER # if $PROMPT_TIMEOUT > 0 this will be used as the max time for proceeding automatically ## function wait() { if [[ "$PROMPT_TIMEOUT" == "0" ]]; then read -rs else read -rst "$PROMPT_TIMEOUT" fi } print_prompt() { # render the prompt x=$(PS1="$DEMO_PROMPT" "$BASH" --norc -i &1 | sed -n '${s/^\(.*\)exit$/\1/p;}') # show command number is selected if $SHOW_CMD_NUMS; then printf "[$((++C_NUM))] $x" else printf "$x" fi } ## # print command only. Useful for when you want to pretend to run a command # # takes 1 param - the string command to print # # usage: p "ls -l" # ## function p() { if [[ ${1:0:1} == "#" ]]; then cmd=$DEMO_COMMENT_COLOR$1$COLOR_RESET else cmd=$DEMO_CMD_COLOR$1$COLOR_RESET fi # wait for the user to press a key before typing the command if [ $NO_WAIT = false ]; then wait fi if [[ -z $TYPE_SPEED ]]; then echo -en "$cmd" else echo -en "$cmd" | pv -qL $[$TYPE_SPEED+(-2 + RANDOM%5)]; fi # wait for the user to press a key before moving on if [ $NO_WAIT = false ]; then wait fi sleep $EXEC_WAIT echo "" } ## # Prints and executes a command # # takes 1 parameter - the string command to run # # usage: pe "ls -l" # ## function pe() { # print the command p "$@" run_cmd "$@" } ## # print and executes a command immediately # # takes 1 parameter - the string command to run # # usage: pei "ls -l" # ## function pei { NO_WAIT=true pe "$@" } ## # Enters script into interactive mode # # and allows newly typed commands to be executed within the script # # usage : cmd # ## function cmd() { # render the prompt x=$(PS1="$DEMO_PROMPT" "$BASH" --norc -i &1 | sed -n '${s/^\(.*\)exit$/\1/p;}') printf "$x\033[0m" read command run_cmd "${command}" } function run_cmd() { function handle_cancel() { printf "" } trap handle_cancel SIGINT stty -echoctl eval "$@" stty echoctl trap - SIGINT print_prompt } function check_pv() { command -v pv >/dev/null 2>&1 || { echo "" echo -e "${RED}##############################################################" echo "# HOLD IT!! I require pv but it's not installed. Aborting." >&2; echo -e "${RED}##############################################################" echo "" echo -e "${COLOR_RESET}Installing pv:" echo "" echo -e "${BLUE}Mac:${COLOR_RESET} $ brew install pv" echo "" echo -e "${BLUE}Other:${COLOR_RESET} http://www.ivarch.com/programs/pv.shtml" echo -e "${COLOR_RESET}" exit 1; } } check_pv # # handle some default params # -h for help # -d for disabling simulated typing # while getopts ":dhncw:" opt; do case $opt in h) usage exit 1 ;; d) unset TYPE_SPEED ;; n) NO_WAIT=true ;; c) SHOW_CMD_NUMS=true ;; w) PROMPT_TIMEOUT=$OPTARG ;; esac done