Bash read: Difference between revisions
(40 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=External= | |||
* https://www.computerhope.com/unix/bash/read.htm | |||
* https://www.baeldung.com/linux/read-command | |||
=Internal= | =Internal= | ||
Line 7: | Line 11: | ||
read [-p prompt] name name2 ... | read [-p prompt] name name2 ... | ||
Read a line from the stdin or from the file descriptor specified with -u, and assign the first word to the variable associated with the first name, the second to the variable associated with the second name, and so on, with the leftover words and their intervening separators assigned to the variable associated with the last name. If there are fewer words than variable names, the variables associated with the remaining names are assigned empty values. | Read a line from the stdin or from the file descriptor specified with -u, and assign the first word to the variable associated with the first name, the second to the variable associated with the second name, and so on, with the leftover words and their intervening separators assigned to the variable associated with the last name. If there are fewer words than variable names, the variables associated with the remaining names are assigned empty values. If no names are supplied, the line read is assigned to the variable REPLY. | ||
The words are split using the [[ | The words are split using the [[Bash_Built-In_Variables#IFS_and_read|IFS characters]]. The backslash character (\) may be used to remove any special meaning for the next character read and for line continuation. | ||
The return code is zero, unless end-of-file is encountered, read times out, or an invalid file descriptor is supplied as the argument to -u. On Ctrl-C, read returns 1. | |||
If -p prompt option is used, read displays the specified prompt on standard error, without a trailing new-line, before attempting to read any input. The prompt is displayed only if input is coming from a terminal. | If -p prompt option is used, read displays the specified prompt on standard error, without a trailing new-line, before attempting to read any input. The prompt is displayed only if input is coming from a terminal. | ||
=Exit Status= | |||
= | The exit status is 0 unless EOF is encountered, the timeout is exceeded, an error occurs assigning a value to name, or the file descriptor provided to [[#-u|-u]] is invalid. | ||
If EOF is encountered, the exit status is 1. | |||
If a timeout is exceeded, the exit status is greater than 128. | |||
=Options= | |||
==<tt>-r</tt>== | |||
Use "raw input". Specifically, this option causes read to interpret backslashes literally, rather than interpreting them as escape characters. | |||
==<tt>-d</tt>== | |||
-d delim | |||
Set the delimiter character to delim. This character signals the end of the line. If -d is not used, the default line delimiter is a newline. | |||
==<tt>-u</tt>== | |||
Read from the specified file descriptor instead of stdin. The file descriptor should be a small integer. | |||
To open a file on a specified file descriptor, see: | |||
{{Internal|Bash_Input/Output#Opening_File_Descriptors_for_Reading_and_Writing|bash Input/Output | Opening File Descriptors for Reading and Writing}} | |||
==<tt>-a</tt>== | |||
See [[#Array_Assignment|Array Assignment]] below. | |||
==<tt>-s</tt>== | |||
See [[#Silent_Mode|Silent Mode]]. | |||
==<tt>-p</tt>== | |||
Prints a prompt. | |||
==<tt>-e</tt>== | |||
Wait until an entire line (new line) is entered. | |||
=Fixed Number of Characters= | ==<span id='Fixed_Number_of_Characters'></span><tt>-n</tt> (Fixed Number of Characters)== | ||
-n nchars | -n nchars | ||
If -n option is used read returns after reading nchars characters rather than waiting for a complete line of input. | If <code>-n</code> option is used read returns after reading nchars characters rather than waiting for a complete line of input. | ||
=Timeout= | |||
-t timeout | |||
causes read to timeout and return failure if a complete line of input is not read within timeout seconds. This option only works if read is reading input from stdin or a pipe. | |||
=Array Assignment= | =Array Assignment= | ||
Line 29: | Line 65: | ||
-a aname | -a aname | ||
If -a option is used, | If -a option is used, the words are assigned to sequential indices of [[Bash_Arrays#Assign_Words_Read_from_stdin_to_an_Array|the array variable]] <tt>aname</tt>, starting at 0. aname is unset before any new values are assigned. Other name arguments are ignored. | ||
See more: {{Internal|Bash_Arrays#Load_an_Array_from_a_Space-Separated_List|bash Arrays}} | |||
=Silent Mode= | =Silent Mode= | ||
Line 36: | Line 74: | ||
If input is coming from a terminal, characters are not echoed. | If input is coming from a terminal, characters are not echoed. | ||
=Examples= | |||
==Confirmation to Proceed== | |||
Note that | |||
<syntaxhighlight lang='bash'> | |||
read -n 1 | |||
</syntaxhighlight> | |||
read the first character and returns immediately without waiting for a new line (which may be a little bit disconcerting) while | |||
<syntaxhighlight lang='bash'> | |||
read -e | |||
</syntaxhighlight> | |||
waits for the new line to be entered. | |||
<syntaxhighlight lang='bash'> | |||
function shall-we-proceed() { | |||
echo "" | |||
echo "This operation is dangerous, shall we proceed?" | |||
echo "" | |||
local answer | |||
read -r -p "y/n: " -n 1 answer || answer="n" | |||
echo "" | |||
[[ ${answer} = "y" ]] && return 0 || return 1 | |||
} | |||
# | |||
# usage | |||
# | |||
if ! shall-we-proceed; then | |||
echo "not proceeding ..." | |||
exit 0 | |||
fi | |||
</syntaxhighlight> | |||
==Read a Password with Confirmation== | |||
<syntaxhighlight lang='bash'> | |||
# | |||
# If --ask-for-confirmation is among arguments, the password will be requested twice, for verification. | |||
# Once a match is confirmed, the value will be returned to stdout. | |||
function read-password() { | |||
local ask_for_confirmation=false | |||
while [[ -n $1 ]]; do | |||
if [[ $1 = "--ask-for-confirmation" ]]; then | |||
ask_for_confirmation=true | |||
fi | |||
shift | |||
done | |||
local password | |||
read -r -s -p "database root password: " password | |||
echo "" 1>&2 | |||
if ${ask_for_confirmation}; then | |||
local password2 | |||
read -r -s -p "repeat database root password: " password2 | |||
echo "" 1>&2 | |||
[[ ${password} != "${password2}" ]] && { echo "passwords do not match" 1>&2; exit 1; } | |||
fi | |||
echo ${password} | |||
} | |||
</syntaxhighlight> | |||
==Reading Lines from File== | |||
{{Internal|Bash_Input/Output#Iterating_over_Lines_from_a_File|Iterating over Lines from a File}} |
Latest revision as of 01:31, 1 March 2024
External
Internal
Overview
read [-p prompt] name name2 ...
Read a line from the stdin or from the file descriptor specified with -u, and assign the first word to the variable associated with the first name, the second to the variable associated with the second name, and so on, with the leftover words and their intervening separators assigned to the variable associated with the last name. If there are fewer words than variable names, the variables associated with the remaining names are assigned empty values. If no names are supplied, the line read is assigned to the variable REPLY.
The words are split using the IFS characters. The backslash character (\) may be used to remove any special meaning for the next character read and for line continuation.
The return code is zero, unless end-of-file is encountered, read times out, or an invalid file descriptor is supplied as the argument to -u. On Ctrl-C, read returns 1.
If -p prompt option is used, read displays the specified prompt on standard error, without a trailing new-line, before attempting to read any input. The prompt is displayed only if input is coming from a terminal.
Exit Status
The exit status is 0 unless EOF is encountered, the timeout is exceeded, an error occurs assigning a value to name, or the file descriptor provided to -u is invalid.
If EOF is encountered, the exit status is 1.
If a timeout is exceeded, the exit status is greater than 128.
Options
-r
Use "raw input". Specifically, this option causes read to interpret backslashes literally, rather than interpreting them as escape characters.
-d
-d delim
Set the delimiter character to delim. This character signals the end of the line. If -d is not used, the default line delimiter is a newline.
-u
Read from the specified file descriptor instead of stdin. The file descriptor should be a small integer.
To open a file on a specified file descriptor, see:
-a
See Array Assignment below.
-s
See Silent Mode.
-p
Prints a prompt.
-e
Wait until an entire line (new line) is entered.
-n (Fixed Number of Characters)
-n nchars
If -n
option is used read returns after reading nchars characters rather than waiting for a complete line of input.
Timeout
-t timeout
causes read to timeout and return failure if a complete line of input is not read within timeout seconds. This option only works if read is reading input from stdin or a pipe.
Array Assignment
-a aname
If -a option is used, the words are assigned to sequential indices of the array variable aname, starting at 0. aname is unset before any new values are assigned. Other name arguments are ignored.
See more:
Silent Mode
-s
If input is coming from a terminal, characters are not echoed.
Examples
Confirmation to Proceed
Note that
read -n 1
read the first character and returns immediately without waiting for a new line (which may be a little bit disconcerting) while
read -e
waits for the new line to be entered.
function shall-we-proceed() {
echo ""
echo "This operation is dangerous, shall we proceed?"
echo ""
local answer
read -r -p "y/n: " -n 1 answer || answer="n"
echo ""
[[ ${answer} = "y" ]] && return 0 || return 1
}
#
# usage
#
if ! shall-we-proceed; then
echo "not proceeding ..."
exit 0
fi
Read a Password with Confirmation
#
# If --ask-for-confirmation is among arguments, the password will be requested twice, for verification.
# Once a match is confirmed, the value will be returned to stdout.
function read-password() {
local ask_for_confirmation=false
while [[ -n $1 ]]; do
if [[ $1 = "--ask-for-confirmation" ]]; then
ask_for_confirmation=true
fi
shift
done
local password
read -r -s -p "database root password: " password
echo "" 1>&2
if ${ask_for_confirmation}; then
local password2
read -r -s -p "repeat database root password: " password2
echo "" 1>&2
[[ ${password} != "${password2}" ]] && { echo "passwords do not match" 1>&2; exit 1; }
fi
echo ${password}
}