Bash Read Don't Error When No Input

Read or dice friends. The read command is just as important every bit positional parameters and the echo control. How else are you going to catch user input, accept passwords, write functions, loop, and peek into file descriptors? Read on.

What is read?

Read is a fustigate builtin command that reads the contents of a line into a variable. Information technology allows for word splitting that is tied to the special beat out variable IFS. Information technology is primarily used for catching user input but can exist used to implement functions taking input from standard input.

Bash read builtin command help

Before we swoop into how to utilise the read command in fustigate scripts, here is how nosotros get assistance. In that location you should meet all the options available for the read control along with descriptions that we will endeavor to embrace in the examples.

Command line

Output

read: read [-ers] [-a assortment] [-d delim] [-i text] [-n nchars] [-N nchars]
[-p prompt] [-t timeout] [-u fd] [proper name ...]

Read a line from the standard input and dissever it into fields.

Reads a single line from the standard input, or from file descriptor FD
if the -u option is supplied.  The line is split up into fields equally with discussion
splitting, and the get-go word is assigned to the first NAME, the 2nd
word to the second NAME, and so on, with whatever leftover words assigned to
the concluding Name.  Only the characters found in $IFS are recognized as discussion
delimiters.

If no NAMEs are supplied, the line read is stored in the Answer variable.

Options:
-a array  assign the words read to sequential indices of the array
variable Array, starting at zero
-d delim continue until the first character of DELIM is read, rather
than newline
-e        utilize Readline to obtain the line in an interactive shell
-i text   use TEXT equally the initial text for Readline
-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
-N nchars return just after reading exactly NCHARS characters, unless
EOF is encountered or read times out, ignoring any
delimiter
-p prompt output the string PROMPT without a trailing newline before
attempting to read
-r exercise non allow backslashes to escape whatsoever characters
-s do not echo input coming from a final
-t timeout fourth dimension out and return failure if a complete line of
input is not read inside TIMEOUT seconds.  The value of the
TMOUT variable is the default timeout.  TIMEOUT may be a
fractional number.  If TIMEOUT is 0, read returns
immediately, without trying to read whatever data, returning
success only if input is available on the specified
file descriptor.  The get out status is greater than 128
if the timeout is exceeded
-u fd read from file descriptor FD instead of the standard input

Exit Status:
The return code is zero, unless end-of-file is encountered, read times out
( in which case it'due south greater than 128), a variable consignment err

Catching user input

Interactive bash scripts are nothing without catching user input. The read builtin provides methods that user input may be caught within a bash script.

Catching a line of input

To catch a line of input NAMEs and options are not required by read. When Proper name is non specified, a variable named Reply is used to store user input.

Commands

{
echo -northward "Type something and printing enter: ";
read;
echo Y'all typed ${REPLY}
}

Output

Type something and press enter: something(newline)
You typed something

Catching a word of input

To catch a word of input, the -d option is required. In the case of a discussion we would set -d to a infinite, read '-d '. That is when the user presses the space bar read will load Reply with the word.

Annotation that when the -d selection is fix, the backspace does not work as expected. To backspace, while trying to catch a give-and-take of input, the -e pick may be used, read -e '-d '.

Commands

{
echo -n "Type something and hit infinite: ";
read '-d ';
repeat "";
echo "You typed ${Answer}"
}

Output

Type something and hitting infinite: something(space)
You typed something

Prompt user

In interactive bash scripts prompting a user may require a bulletin to tell the user what input is expected. Nosotros can always achieve this using the repeat builtin. Notwithstanding, it turns out there is an selection using read.

Prompt user for a discussion

In catching a give-and-take of input, we used echo to write Type something and hitting space: to standard output earlier read '-d '. The -p option allows a message to be displayed earlier reading from standard input.

Commands

{
read -p 'Type something and hit space: ' '-d ';
repeat "";
echo "Y'all typed ${REPLY}"
}

Output

Blazon something and striking infinite: something(space)
You typed something

Prompt user for a underground

When communicable user input without it showing up int the terminal, the -s pick comes in handy. read -south -p allows you to catch and hide user input as follows.

Commands

{
read -s -p 'Type something I promise to keep it a surreptitious: '
echo "";
echo "Your secret is safe with me" ; unset REPLY ;
echo "${REPLY}"
}

Output

Blazon something I hope to continue it a secret:
Your secret is safe with me

Functions using read

Here are examples of functions in fustigate that use read and standard input

Core concept

Functions using read make use of piped standard input and parameters. Main input to be process such as lines in a file are passed in through standard input via a piping. Other input if-whatever and option are passed in as parameters.

read -t 1 NAME1 NAME2 ...

read is a builtin command

-t 1 foreclose the bash script from waiting indefinitely for a line to be returned through standard input. If standard input is initially empty, the function returns with an exit lawmaking of 142 signifying that no engagement was read within the set timeout menses

NAME1 NAME2 are variable names

... many variable names may exist listed

Now that the groundworks are set up, let's encounter what familiar functions look like implemented using read.

Join office using read

Suppose we want a join office that takes a list of words and returns another list of words joined by a delimiter. Here is how we may implement a bring together role using read.

Script

#!/bin/bash
## join
## version 0.0.2 - fix recursion parameters
##################################################
bring together ( ) { { local indelimiter; indelimiter="${i- }" ; local outdelimiter;
outdelimiter="${2-.}" ; }
local automobile
local cdr
local IFS
IFS="${indelimiter}"
read -t 1 motorcar cdr || return
examination "${cdr}" || { echo "${car}" ; return ; }
repeat "${car} ${outdelimiter} ${cdr}" | ${FUNCNAME} "${indelimiter}"
"${outdelimiter}"
}
##################################################
## generated by create-stub2.sh v0.i.2
## on Monday, 17 Jun 2019 12:24:59 +0900
## encounter <https://github.com/temptemp3/sh2>
##################################################

Source: join.sh
Command line

Output

Command line

repeat a b | join | join . \|

Output

Map functions using read

Suppose we want a map function that takes a list and returns some other listing containing the aforementioned number of elements that are modified by another function. Here is how we may implement a map role using read.

Script

#!/bin/bash
## map
## version 0.0.1 - initial
##################################################
map( ) { { local function_name ; function_name="${1}" ; }
local machine
local cdr
local IFS
IFS="${indelimiter- }"
read -t 1 car cdr || return
test "$( declare -f ${function_name} )" || return
examination "${machine}" || { true ; return ; }
${function_name} ${car}
echo "${cdr}" | ${FUNCNAME} "${function_name}"
}
##################################################
## generated by create-stub2.sh v0.1.ii
## on Tue, 18 Jun 2019 08:33:49 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: map.sh
Commands

pow( ) { local -i i=${1} ; echo $( ( i ** 2 ) ) ; }
echo { 1..10 } | map pw

Output

1
4
9
16
25
36
49
64
81
100

Filter function using read

Suppose nosotros want a filter function that takes a list and returns a sublist of elements satifying conditions set by another function. Here is how we may implement a filter function using read.

Script

#!/bin/fustigate
## filter
## version 0.0.1 - initial
##################################################
filter( ) { { local function_name ; function_name="${1}" ; }
local car
local cdr
local IFS
IFS="${indelimiter- }"
read -t 1 machine cdr || return
test "$( declare -f ${function_name} )" || return
examination "${car}" || { true ; return ; }
${function_name} "${car}" || echo -northward "${car} "
echo "${cdr}" | ${FUNCNAME} "${function_name}"
}
##################################################
## generated past create-stub2.sh v0.ane.2
## on Tue, 18 Jun 2019 13:19:54 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Source: filter.sh

Commands

odd( ) { local -i i=${one} ; test ! $( ( i % 2 ) ) -eq 1 ; }
echo { 1..10 } | filter odd

Output

Loops using read

Loops using read allow you to iterate through lines of a file that is to be generated or already exists.

Basic while read loop for the lefthand side (lhs)

We take a command or function (lhs) that can generate lines in a file that can be looped through using read and a while loop.

Construct

lhs | while read
do
true
done
lhs is a control that returns a listing of lines

Commands

seq 5 | while read i
exercise
echo ${i}
done

Output

Basic while read loop for the righthand side (rhs)

We have a file (rhs) with lines that tin can exist looped through using read and a while loop.

Construct

while read
do
true
done < rhs

rhs is a file containing lines

Commands

seq five > rhs
while read i
do
echo ${i}
done < rhs

Output

1
ii
3
iv
five

Custom lhs while loop using read

We accept a stream of words that we would like to loop through using read.

Construct

(
IFS=" "
lhs | while read
do
true
done
)

lhs is a list of words

Commands

(
IFS=" "
echo { i..five } | while read i
practise
echo "${i}
done
)

Output

Reading from any fd instead of standard input

The read builtin pick often left untouched is the ane that allows y'all to specific what file descriptor to read from, read -u FD. By default FD is taken to exist standard input.

Cadre concept

When a file opened file descriptors are assigned. IO redirection in fustigate allow a file to exist left  open up with a specific file descriptor. We are allowed to write to the file, read from it, and shut it when we are washed.

_ ( )
{
cat /dev/null > myfifo; # empty myfifo
exec 3 < myfifo; # open file myfifo as fd 3
echo "Hello, World! - from fd iii" > myfifo; # write to myfifo
read -u 3; # read line from fd 3
exec 3 >&-; # shut fd 3
echo ${Reply} # output line read from fd iii before closing
}
_ # Hello, World! from fd 3

Building a train with file descriptors and read -u FD

Simply for fun I decided to build a train with file descriptors and read -u FD. To each file descriptor a number is written. Each file descriptor reads from the file descriptor 1 beneath and appends to itself.

Command line

fustigate linuxhint.com/build/test-read-fd.sh train x

Output

initializing fds ...
initializing fd 3 ...
fd three intialized
initializing fd 4 ...
fd 4 intialized
fds intialized
reading from fd iii and four ...
4 3
fds before cleaning upward
0 ane 2 3 4 5
cleaning upwards ...
cleaning upward fds ...
washed cleaning up fds
fds after cleaning upwards
0 1 2 3

Skip function using read -u FD

If y'all are running

uname -a
MINGW64_NT-10.0 DESKTOP-XVVVVVV 2.7.0( 0.307 / v / 3 )
2017-02-17 14:twenty x86_64 Msys
bash --version
GNU fustigate, version iv.4.12( 1 )-release (x86_64-pc-msys)

it may be possible due to a bug to implement a skip office that skips the following line in a bash script outside of functions earlier the script source is read. Note that it does not work on most systems. For example,

uname -a
Linux 4.ix.0-8-amd64 #ane SMP Debian 4.9.144-3.1 (2019-02-19) x86_64 GNU/Linux
bash --version
GNU bash, version 4.4.12( 1 )-release (x86_64-pc-linux-gnu)

skip does not fly.

Function

skip ( ) { read -u 31 ; }

Commands

skip
echo line skipped
truthful

Output

Bottom line

The read builtin in bash does more catch user input. It tin can exist used in functions, loops and exchanges between file descriptors used in bash scripts. On occasion exploration using read and file descriptors may yield Easter eggs.

About the author

A developer and advocate of trounce scripting and vim. His works include automation tools, static site generators, and web crawlers written in bash. For work he tools with cloud computing, app evolution, and chatbots. He codes in bash, python, or php, but is open to offers.

carrollouldives49.blogspot.com

Source: https://linuxhint.com/bash_read_command/

0 Response to "Bash Read Don't Error When No Input"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel