LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 01-30-2010, 01:06 AM   #1
Caed Lucin
LQ Newbie
 
Registered: Jan 2010
Posts: 3

Rep: Reputation: 0
How to make shell script wait for a particular key pressed in order to proceed?


Hello,

This is a question for shell scripting. Uhmm i've been searching all over the internet for a way to let the user press a particular key let's say 'y' without the user having to press [Enter] as confirmationfor yes, this would then run another function.

like say..


Quote:
Book Inventory Summary Report:-

Title, Author, Price
______________________________
StarWars EP1, G.Lucas, $49.59
Harry Potter, Rowling, $45.98
The Matrix, Mr. Smith, $53.98


Press 'y' to make a copy of this result into a file or 'n' to return to the main menu..

I understand the "press any key to continue" would go something like

Code:
read -sn 1 -p "Press any key to continue.."
But i try many different ways of getting the "press a particular key" function, and none of them works. Any help would be much appreciated! Thanks you!
 
Old 01-30-2010, 01:18 AM   #2
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Try something like
Code:
prompt='Press n for no or y for yes '
echo -n "$prompt"
while read -n1 char
do
    case $char in
        n | N )
            # <commands as required>
            break
            ;;
        y | Y )
            # <commands as required>
            break
            ;;
        * )
            echo -ne "\nInvalid character '$char' entered. $prompt"
    esac
done
 
Old 01-30-2010, 01:44 AM   #3
Caed Lucin
LQ Newbie
 
Registered: Jan 2010
Posts: 3

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by catkin View Post
Try something like
Code:
prompt='Press n for no or y for yes '
echo -n "$prompt"
while read -n1 char
do
    case $char in
        n | N )
            # <commands as required>
            break
            ;;
        y | Y )
            # <commands as required>
            break
            ;;
        * )
            echo -ne "\nInvalid character '$char' entered. $prompt"
    esac
done
Wow! Thank you very much catkin! That worked! But here's the problem, when i press the arrow keys instead of any other keys, my next input for main menu choice would go haywire.

as my program's menu structure goes like this..

Book Inventory Program
1) Add book
2) Remove book
3) Update book
4) Search book
5) Process book sold
6) Inventory Summary Report <<-- This is where the "press a particular key" thing is implemented.
7) Quit


Anyway below is my function just in case you guys need to see it. It's pretty messy and i'm not sure if there's any way i could save the awk printout into a file without having to copy the whole awk command again for file saving process.

Code:
function inventory_summary_report
{
	echo "##########################"
    echo " INVENTORY SUMMARY REPORT"
	echo "##########################"

	echo ""
	cat $FILENAME | sort | awk -F':' 'BEGIN { 
				format1="%-45s %-20s %-20s %-20s %-20s %-20s\n"
				format2="%-45s %-20s $%-20.2f %-20d %-20d $%.2f\n"
				printf (format1, "Title", "Author", "Price", "Qty Avail", "Qty Sold", "Total Sales")
				printf  "_____________________________________________________________________________________________________________________________________________\n"}
				{ printf (format2, $1, $2, $3, $4, $5, $3*$5); }'
	echo ""
	echo "Press 'Y' to make a copy of the inventory summary report or any other key to return to main menu.."

	while read -sn1 keyPressed
	do
		case $keyPressed in
			y | Y )		cat $FILENAME | sort | awk -F':' 'BEGIN { 
				format1="%-45s %-20s %-20s %-20s %-20s %-20s\n"
				format2="%-45s %-20s $%-20.2f %-20d %-20d $%.2f\n"
				printf (format1, "Title", "Author", "Price", "Qty Avail", "Qty Sold", "Total Sales")
				printf  "_____________________________________________________________________________________________________________________________________________\n"}
				{ printf (format2, $1, $2, $3, $4, $5, $3*$5); }' >> Hello.txt;
						echo "Returning to main menu.." ;
						break;;
			n | N )		echo "Returning to main menu.." ; return ; break ;;
			* )			tput setf 4 ; echo "Please press either 'y' or 'n'.."; tput setf 0 ;;
		esac
	done
}
 
Old 01-30-2010, 03:44 AM   #4
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,551
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Quote:
Originally Posted by Caed Lucin View Post
But here's the problem, when i press the arrow keys instead of any other keys, my next input for main menu choice would go haywire.
True

Unfortunately bash does not have a non-blocking read facility so there's no way to empty the terminal input (keyboard) buffer. It could be done by writing a custom "external command" (that's bash-speak) as mentioned here.

A version of bash later than the 3.1.7 used for testing introduced fractions of a second on read's -t option. GNU Bash Reference says this about read: "-t timeout Cause read to time out and return failure if a complete line of input is not read within timeout seconds. timeout may be a decimal number with a fractional portion following the decimal point."

This could be used with a low timeout value to approximate a non-blocking read, something like this to go at the top of the * case code above (it's a bit ugly, maybe putting a string in a variable called char!)
Code:
while read -t '0.01' -n1 buf
do
    char="$char$buf"
done
 
Old 01-31-2010, 12:15 AM   #5
Caed Lucin
LQ Newbie
 
Registered: Jan 2010
Posts: 3

Original Poster
Rep: Reputation: 0
Ahhh i see, well it didn't work out the way i hope it would, but thank you very much for your help catkin!

I'll still use the case thing but will keep my fingers crossed hoping the the person assessing my assignment ain't gonna hit the arrow keys. hahaha.
 
Old 01-31-2010, 06:08 PM   #6
trey85stang
Senior Member
 
Registered: Sep 2003
Posts: 1,090

Rep: Reputation: 41
small change to catkins code...

Code:
while true
do  
  prompt='Press n for no or y for yes '
  echo -n "$prompt"
  read -n1 char
  case "$char" in
      [Nn])
          # <commands as required>
          break
          ;;
      [Yy])
          # <commands as required>
          break
          ;;
      *)
          echo -ne "\nInvalid character '$char' entered.\nPlease try again"
          continue
    esac
done
I like brackets better then piping n case so I just changed them.. either way works. This will put you in a loop, so the question is re-asked if YyNn is not selected.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to compare a text value in a shell script and proceed accordingly hemantsankhla Linux - Newbie 8 09-18-2009 12:42 AM
How to make shell script wait for key press to proceed... ddenton Linux - General 13 12-02-2008 04:25 AM
Wait for one of two processes to complete in a shell script nonoitall Programming 11 06-10-2008 04:10 PM
Which ioctl to use to get the key pressed in the key board? Sreeram B S Linux - Kernel 0 02-24-2007 02:02 AM
Make script wait for input farmerjoe Linux - General 4 12-28-2004 01:49 AM


All times are GMT -5. The time now is 07:37 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration