Bash timeout on 'read' command - bash

I have a pretty simple bash script that sends command to serial and reads thee value back. The problem is when I don't get a value back,, it can get stuck.
echo BC > /dev/ttyS1
read line < /dev/ttyS1
echo $line
I have used the cat command with a timeout, but cannot use the same technique with 'read', because if I send the process to the background, I never get value back on exit. 'cat' works for the most part, but i'm not sure if this is the most robust way to do this.
echo BC > /dev/ttyS1
cat /dev/ttyS1 &
pid=$!
sleep 0.1
kill -9 $pid

From section 4.2 Bash Builtin Commands of the Bash Reference Manual:
read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name …]
...
-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 option is only effective if read is reading input from a terminal, pipe, or other special file; it has no effect when reading from regular files. If timeout is 0, read returns success if input is available on the specified file descriptor, failure otherwise. The exit status is greater than 128 if the timeout is exceeded.

Related

How can I get a Bash shell script to listen for a keypress while running, rather than pause and wait for it? [duplicate]

I can ask the user to press Enter by using read, and have him wait by calling sleep. But I can’t think of a way of doing both at the same time. I would like the user to be given the choice:
Press Ctrl+C to Cancel, Enter to continue or just wait 10 seconds
How can I do that?
In bash(1), read has a -t option where you can specify a timeout. From the manpage:
read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...]
-t timeout: cause read to time out and return failure if a complete line of input is not read within timeout seconds. This option has no effect if read is not reading input from the terminal or a pipe.
Transcript below (without hitting ENTER):
$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; echo ; date
Tue Feb 28 22:29:15 WAST 2012
Hit ENTER or wait ten seconds
Tue Feb 28 22:29:25 WAST 2012
Another, hitting ENTER after a couple of seconds:
$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; date
Tue Feb 28 22:30:17 WAST 2012
Hit ENTER or wait ten seconds
Tue Feb 28 22:30:19 WAST 2012
And another, hitting CTRL-C:
$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; echo ; date
Tue Feb 28 22:30:29 WAST 2012
Hit ENTER or wait ten seconds
(1) If you're doing this in a script, make sure that it's a bash one. You can do that by adding a shebang line at the start such as one of the following:
#!/usr/bin/env bash
#!/bin/bash
The read builtin has a timeout.
read -t 10
will do it
Building on the thoughtful answers above, the return value from the read is useful to distinguish between an empty response from the user (for example "Press Enter" for the default action) and a timeout.
read -t 5 -p "Prompt " RESP
if [[ $? -gt 128 ]] ; then
echo -e "\nTimeout"
else
echo "Response = \"$RESP\"" # adding quotes so empty strings are obvious
fi
Another useful tidbit is that the -p "prompt " is written to stderr (not stdout) so if you're redirecting stderr, the prompt will not be displayed. An example of this would be logging an execution trace to a log file for later analysis. To use read -p Prompt in this case you can redirect stderr to the user for just the read statement.
set -x
exec 2>logfile
read -t 5 -p "Prompt " RESP 2>/dev/tty
From the bash reference manual :
read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt][-t timeout][-u fd] [name ...]

"read: -a: unknown option" when running script with ksh

Hello i was able to run one of the script from putty terminal without any issue as follows
sh file_validation_generic.sh 1 /test/data/infa_shared/dev/scripts
but when i try to execute the script from a tool it is giving below error
sh -c "ksh /test/data/infa_shared/dev/scripts/file_validation_generic.sh 1 /test/data/infa_shared/dev/scripts"
error :-
/test/data/infa_shared/dev/scripts/file_validation_generic.sh[121]: read: -a: unknown option
Usage: read [-ACprsSv] [-d delim] [-u fd] [-t timeout] [-n count] [-N count]
[var?prompt] [var ...]
this error occurs in a while loop during the read to an array
IFS="~"
read -a star <<< "$line"
col_pos=${star[1]}
col_patt=${star[6]}

Setting a date to embedded system using shell script

i'm using embedded linux here i need to set the current date to system which is based on user input given by the key board,here i'm failing at one condition that is the system has to wait for 2 minutes un till gets input from keyboard if it reaches to specified wait time it has to come out from loop.......
Below is my piece of code:
echo please enter the date in below format
echo YEAR- MM-DD HRS:MNS:SEC and press enter
read -e a1
startd=$(date -s "$a1");
echo "$startd";
hwclock --systohc
date
You should use option -t in your the read command:
if read -e -t 120 a1; then
echo "input: $a1"
else
echo "no input"
fi
From the bash man page:
read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
...
-t timeout
Cause read to time out and return failure if a complete line of input (or a specified number of characters) is not read within timeout seconds.

Cant run bash script example from "The linux command line, a complete introduction, 2nd"

Here is an example of my zsh script, that script was modified from original one:
#!/bin/sh
set -e
# read-default.sh: supply a default value if user preses Enter key.
read -e -p "What is your user name? " -i $USER
echo "You answered: '$REPLY'"
Here is an original script from the book:
#!/bin/bash
# read-default: supply a default value if user presses Enter key.
read -e -p "What is your user name? " -i $USER
echo "You answered: '$REPLY'"
Here is a mistake what I've got after running zsh script:
read-default.sh: line 7: read: -i: invalid option
read: usage: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array]
[-n nchars] [-d delim] [name ...]
I will be appreciate for any help! :)
What language is your script written in?
Shell scripts written in bash, zsh, and sh differ slightly.
It seems your are using bash features, but run the code with sh.
The read command is a shell builtin. Have a look at the corresponding man pages to find out what kind of options are allowed for your shell.
For your example it should be enough to change the shebang (first line) back to #!/bin/bash or run the script explicitly with bash read-default.sh.
As you see in your shell's error message, you cannot use the -i flag when calling read. To solve your problem you need to check if $REPLY is empty and supply a default value if it is.

Offering a default on return in a shell script input prompt

I inappropriately asked my question on 'How do I prompt for input in a Linux shell script?'
I've gone through the 'Questions with similar titles' list and cannot see an answer.
I obviously don't have bash4 as the following doesn't work:
$ read -e -p "Enter database SID, or just return for default: " -i "swmfolx" ORACLE_SID
-bash: read: -i: invalid option
read: usage: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
'All' I am trying to do is prompt for input with the option of just return for the default.
Any links or advice would be gratefully acknowledged.
You'll need to do this as follows:
read -p "Enter database SID: " dbsid
if [ "$dbsid" = "" ]
then
dbsid="mydefaultvalue"
fi
...essentially, read the value and if all they've done is hit enter, it assigns the default value.

Resources