Reputation:
I just wanted to write a small sript for copying some files for my NAS, so I'm not very experienced in Shell-Scripting. I know that many command line tools on Linux use the following sheme for Yes/No inputs
Are you yure [Y/n]
where the capitalized letter indicates the standard action which would also be started by hitting Enter. Which is nice for a quick usage.
I also want to implement something like this, but I have some trouble with caching the Enter key. Here is what I got so far:
read -p "Are you sure? [Y/n] " response
case $response in [yY][eE][sS]|[yY]|[jJ]|[#insert ENTER codition here#])
echo
echo files will be moved
echo
;;
*)
echo
echo canceld
echo
;;
esac
I can add what ever I want but it just won't work with Enter.
Upvotes: 4
Views: 7197
Reputation: 625
A few years passed since the question was asked, but since it's still relevant in searches I thought I'd provide the different method I ended up using.
I wanted to lock the question in place until a y/n/enter is pressed and without spamming the prompt request, so I (ab)used the -s
echo suppression and came up with the following:
#!/bin/bash
echo -n "Confirm action [y/N]? "
while true; do
read -sn1 response
case "$response" in
[yY]) echo 'y'; break;;
[nN]|"") echo 'n'; exit 0;;
esac
done
Upon N or Enter the script is ended, otherwise it just goes on as intended. The additional echos to output user choice is not necessary, but I left it in as a visual feedback.
Also, by moving the |""
around, you can default the enter key to either yes or no responses.
Upvotes: 1
Reputation: 31
Since you gave option [y/n], the code can be changed something like (edited):
#!/bin/bash
while true
do
echo "Are you sure? [Y/n]?"
read response
case $(echo ${response:-Y}|tr '[:lower:]' '[:upper:]') in
Y|YES)
echo "files will be moved!"
break
;;
N|NO)
echo "aborted!"
exit
;;
*)
echo "incorrect selection!"
;;
esac
done
Upvotes: 1
Reputation: 853
This has input validation that accepts "Y", "y", "an empty string" or "n" and "N" as valid input for the question [Y/n].
#!/bin/bash
while : ; do # colon is built into bash; and is always true.
read -n1 -p "Are you sure? [Y/n] " response
echo
case "$response" in
y|Y|"") echo "files will be moved"; break ;; # Break out of while loop
n|N) echo -e "canceled"; break ;; # Break out of while loop
*) echo "Invalid option given." ;;
esac
done
Upvotes: 4
Reputation: 2343
Here's a quick solution:
read -p "Are you sure? [Y/n] " response
case $response in [yY][eE][sS]|[yY]|[jJ]|'')
echo
echo files will be moved
echo
;;
*)
echo
echo canceled
echo
;;
esac
Upvotes: 5
Reputation: 531165
If you are using bash
4, you can "pre-seed" the response with the default answer, so that you don't have to treat ENTER
explicitly. (You can also standardize the case of response
to simplify the case
statement.
read -p "Are you sure? [Y/n] " -ei "y" response
response=${response,,} # convert to lowercase
case $response in
y|ye|yes)
echo
echo files will be moved
echo
;;
*)
echo
echo cancelled
echo
;;
Upvotes: 5
Reputation: 785146
You should use read -n1
read -n1 -p "Are you sure? [Y/n] " response
case "$response" in
[yY]) echo "files will be moved";;
?) echo "canceled";;
esac
As per help read
:
-n nchars return after reading NCHARS characters rather than waiting
for a newline, but honor a delimiter if fewer than NCHARS
characters are read before the delimiter
Upvotes: 3