1

How can i get this feature to work?

Pressing Esc while taking inputs from the user will exit the script

read -r -p "Enter the filenames: " -a arr

if press Esc; then
     read $round
     mkdir $round
fi

for filenames in "${arr[@]}"; do
   if [[ -e "${filenames}" ]]; then
        echo "${filenames} file exists (no override)"
   else
        cp -n ~/Documents/library/normal.cpp "${filenames}"
   fi
done

How can i detect Esc key in this script?

PS: Saw many resources
https://www.linuxquestions.org/questions/linux-newbie-8/bash-esc-key-in-a-case-statement-759927/
they use another variable like $key or read -n1 $key just one character input

but here what will i do if I've a string or an array?

6
  • 5
    Since you want to exit the script anyway when Esc is pressed, why not use the usual Ctrl+C to terminate the script? If there are reasons against it, please edit your post to clarify.
    – AdminBee
    Jul 5, 2022 at 11:38
  • i just used an example.. Ok will clarify
    – Mega Bang
    Jul 5, 2022 at 11:40
  • 3
    Why do you want to prompt your users instead of just reading arguments from the command line? Prompting is hard, it means the script cannot be automated, it cannot be run again with the same arguments and it is very easy to make a typo if laboriously writing out the file names, while when passing them as arguments you can use tab-completion. So maybe you don't need this feature at all?
    – terdon
    Jul 5, 2022 at 11:53
  • 1
    Above script is just a dummy one. With a healthy mind, i do need this feature
    – Mega Bang
    Jul 5, 2022 at 12:03
  • 1
    What keeps you from trying an adaption of your referred quote, like while read Arg; do case $Arg in (*$'\e'*) echo Escape;; *) echo $Arg;; esac; done? Be aware that here the "return" key is needed to complete the read; an immediate reaction on <ESC> is not possible.
    – RudiC
    Jul 5, 2022 at 12:57

2 Answers 2

1

The best solution is to read the file paths from a file or pass them as arguments to the script, like @terdon said

The best way to exit read on an Escape key press seems to be: https://superuser.com/questions/1267984/how-to-exit-read-bash-builtin-by-pressing-the-esc-key/1447324#1447324

Another inferior way (it cannnot differentiate between Esc and arrow key presses):

#!/usr/bin/env bash


inputString=''

clear() { printf '\033c'; }

ask() {
    clear
    printf '%s' "Enter the filenames: $inputString"
}

ask

while :; do
    read -rN 1 char

    case "$char" in
        $'\e') # Esc (or arrow) key pressed
            clear
            exit
            ;;
        $'\n') # Enter key pressed
            break
            ;;
        $'\177') # Backspace key pressed
            [[ "${#inputString}" -gt 0 ]] &&
                inputString="${inputString::-1}"

            ask
            continue
            ;;
        *)
            ;;
    esac

    [[ -n "$char" ]] &&
        inputString+="$char"
done


array_fromString() {
    local -n array_fromString_a="$1"

    local IFS=$'\n'
    array_fromString_a=(
        $(xargs -n1 <<< "$2")
    )
}


files=()
array_fromString files "$inputString"
echo "Entered filenames: "
printf '%s\n' "${files[@]}"
0

Here's how I tweaked my script. Hope it helps.

This should work in bash:

#!/bin/bash

# Bind the Escape key to run "escape_function" when pressed.
bind_escape () { bind -x '"\e": escape_function' 2> /dev/null; }

# Unbind the Escape key.
unbind_escape () { bind -r "\e" 2> /dev/null; }

escape_function () {

unbind_escape
echo "escape key pressed"
# command/s to be executed when the Escape key is pressed
exit

}

bind_escape

# Use read -e for this to work.
read -e -r -p "Enter the filenames: " -a arr

unbind_escape

# Commands to be executed when Enter is pressed.
for filenames in "${arr[@]}"; do
   if [[ -e "${filenames}" ]]; then
        echo "${filenames} file exists (no override)"
   else
        cp -n ~/Documents/library/normal.cpp "${filenames}"
   fi
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .