Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Shell Script Dictionary
  3. read

read

Since: read(基本) POSIX(sh互換)
-p / -s / -t / -n / -a(bash拡張オプション) Bash(bash拡張)

The read command in shell scripts is a built-in command that reads one line from standard input and stores it in a variable. It is useful in a wide range of situations, including prompting the user for input, reading passwords without displaying them on screen, and processing files line by line. The -p option displays a prompt string before accepting input, and -s reads input silently without echoing characters to the terminal. The while read line pattern is the standard idiom for processing standard input or a file one line at a time.

Basic Syntax

read is used in the form read [options] variable.... When multiple variable names are specified, the input line is split on IFS delimiters and each field is stored in the corresponding variable. If no variable name is given, the input is stored in the special variable REPLY.

SyntaxDescription
read varReads one line from standard input and stores it in the variable var.
read var1 var2 ...Splits the line on IFS and stores each field in the corresponding variable in order. Any remaining fields are all stored in the last variable.
read (no variable name)Stores the line that was read in the built-in variable REPLY.
read -r varDoes not interpret backslashes as escape characters. Using -r is recommended whenever reading from a file.
read -p "string" varDisplays a prompt string before waiting for input (bash only).
read -s varDoes not echo the input characters to the screen. Used for password input.
read -t seconds varTimes out if no input is received within the specified number of seconds. The exit status is 1 on timeout.
read -n count varAutomatically finishes reading after the specified number of characters. No Enter key press is required.
read -d char varUses the specified character as a delimiter instead of a newline.
read -a arraySplits the input on IFS and stores it in an array (bash only).
# Basic form of read
read var

# Split into multiple variables (IFS defaults to space, tab, and newline)
read var1 var2 var3

# Standard pattern for reading a file (-r treats backslashes literally)
while IFS= read -r line; do
    echo "${line}"
done < filename

# Input with a prompt (bash)
read -p "Enter your name: " name

# Silent input (e.g., for passwords)
read -s -p "Password: " password
echo ""   # read -s does not output a newline, so we add one manually

Relationship with IFS

IFS (Internal Field Separator) is a shell variable that defines the delimiter characters used to split input. When read stores a single line into multiple variables, it uses the value of IFS as the delimiter. The default value consists of three characters: space, tab, and newline.

IFS SettingBehavior
Default (space, tab, newline)Treats consecutive spaces or tabs as a single delimiter. Leading and trailing whitespace is automatically stripped.
IFS= (empty string)Performs no splitting. The entire line is stored as-is in a single variable. Leading and trailing whitespace is preserved. This is the recommended setting when reading files.
IFS=: (colon)Splits on colons. Useful for parsing formats like /etc/passwd.
IFS=$'\t' (tab)Splits on tabs. Useful for parsing TSV files.
IFS=, (comma)Splits on commas. Useful for simple CSV parsing.

When changing IFS, it is safest to specify it inline immediately before the read command, in the form IFS=delimiter read -r variable. This way the change to IFS is only in effect during the execution of read and does not affect the global shell environment.

# Specifying IFS inline (does not pollute the shell-wide IFS)
IFS=: read -r field1 field2 field3 <<< "aaa:bbb:ccc"

# Reading an entire line with IFS= to preserve whitespace
while IFS= read -r line; do
    echo "${line}"
done < data.txt

# Splitting a tab-delimited line with IFS=$'\t'
while IFS=$'\t' read -r col1 col2 col3; do
    echo "${col1} / ${col2} / ${col3}"
done < data.tsv

The while read Pattern

To process a file or standard input one line at a time, while IFS= read -r line; do ... done < file is the most commonly used approach. IFS= prevents whitespace trimming, and -r treats backslashes as literal characters.

PatternDescription
while IFS= read -r line; do ... done < fileThe most basic pattern, passing a file via redirection. Preserves leading and trailing whitespace on each line.
command | while IFS= read -r line; do ... donePipes command output into the loop. Because the pipe runs in a subshell, variables modified inside the loop are not available in the parent shell.
while IFS= read -r line; do ... done <<< "$var"Processes a variable's content line by line using a here string. No subshell is created, so variables are accessible in the parent shell.
while IFS=$'\t' read -r f1 f2; do ... done < fileStores each tab-delimited field in a separate variable. Well-suited for TSV parsing.
while IFS= read -r line || [ -n "$line" ]; do ... done < fileEnsures the last line is not missed even if the file does not end with a newline.

Sample Code

kof_read_basic.sh
#!/bin/bash
# -----------------------------------------------
#  Demonstrates the basic usage of the read command
#  using characters from The King of Fighters (KOF)
# -----------------------------------------------

# -----------------------------------------------
#  1. read var — reads one line from standard input into a variable
# -----------------------------------------------

echo "=== KOF Fighter Registration System ==="
echo ""

# Read input and store it in the fighter variable
read -p "Enter the name of the fighter to register: " fighter

echo ""
echo "  ${fighter} has entered!"
echo ""

# -----------------------------------------------
#  2. Splitting input into multiple variables with read
# -----------------------------------------------

echo "--- Team Registration (enter 3 names separated by spaces) ---"
echo ""

# Uses the default IFS (space) to split into three variables
read -p "Fighter1 Fighter2 Fighter3: " member1 member2 member3

echo ""
echo "  Team lineup:"
echo "    1st: ${member1}"
echo "    2nd: ${member2}"
echo "    3rd: ${member3}"
$ chmod +x kof_read_basic.sh
$ ./kof_read_basic.sh
=== KOF Fighter Registration System ===

Enter the name of the fighter to register: Terry Bogard

  Terry Bogard has entered!

--- Team Registration (enter 3 names separated by spaces) ---

Fighter1 Fighter2 Fighter3: Terry Joe Shermie

  Team lineup:
    1st: Terry
    2nd: Joe
    3rd: Shermie
kof_read_options.sh
#!/bin/bash
# -----------------------------------------------
#  Demonstrates read -p / -s / -t / -n options
#  using characters from KOF
# -----------------------------------------------

# -----------------------------------------------
#  -p option: displays a prompt before waiting for input
# -----------------------------------------------

echo "=== KOF Ranking Board ==="
echo ""

# -p displays a prompt string (bash only)
# Input is accepted immediately after the prompt on the same line
read -p "Enter your fighter name: " player_name

echo "  Welcome, ${player_name}!"
echo ""

# -----------------------------------------------
#  -s option: does not echo input to the screen
# -----------------------------------------------

echo "--- Enter your secret special move code ---"
echo ""

# -s hides the input characters (used for passwords and secret codes)
# Combined with -p to display a prompt at the same time
read -s -p "Special move code (hidden): " secret_code
echo ""   # read -s does not output a newline after input, so we add one manually

# Show only the length of the input, not the content itself
code_len=${#secret_code}
echo "  Special move code accepted (${code_len} characters)"
echo ""

# -----------------------------------------------
#  -t option: sets a timeout (in seconds)
# -----------------------------------------------

echo "--- Select a fighter within 3 seconds ---"
echo ""

# -t 3 times out if no input is received within 3 seconds
# The exit status is 1 on timeout
if read -t 3 -p "Fighter selection (3 sec): " chosen_fighter; then
    echo ""
    echo "  You selected ${chosen_fighter}!"
else
    echo ""
    echo "  Timed out. Selecting Kula Diamond as the default."
    chosen_fighter="Kula Diamond"
fi

echo ""

# -----------------------------------------------
#  -n option: auto-confirms after the specified number of characters
# -----------------------------------------------

echo "--- Select difficulty (1 character): 1=Easy 2=Normal 3=Hard ---"
echo ""

# -n 1 confirms immediately after 1 character without requiring Enter
read -n 1 -p "Difficulty (1/2/3): " difficulty
echo ""   # -n does not output a newline after input, so we add one manually

case "${difficulty}" in
    1) echo "  Difficulty: Easy — have fun practicing with ${chosen_fighter}!" ;;
    2) echo "  Difficulty: Normal — put ${chosen_fighter}'s skills to the test!" ;;
    3) echo "  Difficulty: Hard — show the true power of ${chosen_fighter}!" ;;
    *) echo "  Invalid selection. Difficulty set to Normal." ;;
esac
$ chmod +x kof_read_options.sh
$ ./kof_read_options.sh
=== KOF Ranking Board ===

Enter your fighter name: Terry Bogard
  Welcome, Terry Bogard!

--- Enter your secret special move code ---

Special move code (hidden):
  Special move code accepted (8 characters)

--- Select a fighter within 3 seconds ---

Fighter selection (3 sec): Kula Diamond
  You selected Kula Diamond!

--- Select difficulty (1 character): 1=Easy 2=Normal 3=Hard ---

Difficulty (1/2/3): 3
  Difficulty: Hard — show the true power of Kula Diamond!
kof_while_read_file.sh
#!/bin/bash
# -----------------------------------------------
#  Demonstrates file line processing with while read
#  using characters from KOF
# -----------------------------------------------

# -----------------------------------------------
#  Create a data file
#  Format: character name[TAB]team[TAB]nationality
# -----------------------------------------------

data_file="/tmp/kof_fighters.tsv"

# Write tab-delimited data using a here document
cat > "${data_file}" <<'EOF'
Terry Bogard	Fatal Fury Team	USA
Kyo Kusanagi	Japan Team	Japan
K'	K' Team	Unknown
Kula Diamond	Anti-K' Team	Antarctica
Athena Asamiya	Women Fighters Team	Japan
EOF

echo "=== KOF Fighter Encyclopedia ==="
echo ""

# -----------------------------------------------
#  Split tab-delimited columns into variables with IFS=$'\t' read -r
#  - IFS=$'\t' : use tab as the delimiter
#  - -r         : treat backslashes as literal characters
#  - < "${data_file}" : pass the file via redirection
# -----------------------------------------------

count=0
while IFS=$'\t' read -r name team country; do
    count=$((count + 1))
    printf "  %d. %-22s  Team: %-22s  Nationality: %s\n" \
        "${count}" "${name}" "${team}" "${country}"
done < "${data_file}"

echo ""
echo "Registered fighters: ${count}"
echo ""

# -----------------------------------------------
#  Example of preserving the full line with IFS= read -r
#  Leading and trailing whitespace and tabs are not trimmed
# -----------------------------------------------

echo "=== Raw data check (whitespace preserved with IFS=) ==="
echo ""

# Specifying IFS= stores the entire line as-is in the line variable
while IFS= read -r line; do
    echo "  |${line}|"
done < "${data_file}"

# Remove the temporary file
rm -f "${data_file}"
$ chmod +x kof_while_read_file.sh
$ ./kof_while_read_file.sh
=== KOF Fighter Encyclopedia ===

  1. Terry Bogard          Team: Fatal Fury Team        Nationality: USA
  2. Kyo Kusanagi          Team: Japan Team             Nationality: Japan
  3. K'                    Team: K' Team                Nationality: Unknown
  4. Kula Diamond          Team: Anti-K' Team           Nationality: Antarctica
  5. Athena Asamiya        Team: Women Fighters Team    Nationality: Japan

Registered fighters: 5

=== Raw data check (whitespace preserved with IFS=) ===

  |Terry Bogard	Fatal Fury Team	USA|
  |Kyo Kusanagi	Japan Team	Japan|
  |K'	K' Team	Unknown|
  |Kula Diamond	Anti-K' Team	Antarctica|
  |Athena Asamiya	Women Fighters Team	Japan|
kof_read_interactive.sh
#!/bin/bash
# -----------------------------------------------
#  Implements an interactive menu with while read
#  using characters from KOF
# -----------------------------------------------

# -----------------------------------------------
#  KOF fighter information database (managed as arrays)
# -----------------------------------------------

names=("Terry Bogard" "Kyo Kusanagi" "K'" "Kula Diamond" "Athena Asamiya")
teams=("Fatal Fury Team" "Japan Team" "K' Team" "Anti-K' Team" "Women Fighters Team")
origins=("USA" "Japan" "Unknown" "Antarctica" "Japan")

echo "=== KOF Fighter Search System ==="
echo "  Type 'quit' to exit"
echo ""

# -----------------------------------------------
#  Use while read to repeatedly accept user input
#  - read -p displays the prompt
#  - break exits the loop when the input is 'quit'
# -----------------------------------------------

while read -r -p "Enter fighter number (1-5) or 'quit': " input; do

    # Exit the loop if 'quit' is entered
    if [ "${input}" = "quit" ]; then
        echo ""
        echo "Exiting the system."
        break
    fi

    # Check that the input is a number (integers only)
    if ! echo "${input}" | grep -qE '^[0-9]+$'; then
        echo "  Please enter a number or 'quit'."
        echo ""
        continue
    fi

    # Check that the number is in the range 1-5
    if [ "${input}" -lt 1 ] || [ "${input}" -gt 5 ]; then
        echo "  Please enter a number between 1 and 5."
        echo ""
        continue
    fi

    # Arrays are zero-indexed, so adjust the index
    idx=$((input - 1))

    echo ""
    echo "  ----------------------------------------"
    echo "  Name        : ${names[$idx]}"
    echo "  Team        : ${teams[$idx]}"
    echo "  Nationality : ${origins[$idx]}"
    echo "  ----------------------------------------"
    echo ""
done
$ chmod +x kof_read_interactive.sh
$ ./kof_read_interactive.sh
=== KOF Fighter Search System ===
  Type 'quit' to exit

Enter fighter number (1-5) or 'quit': 1

  ----------------------------------------
  Name        : Terry Bogard
  Team        : Fatal Fury Team
  Nationality : USA
  ----------------------------------------

Enter fighter number (1-5) or 'quit': 4

  ----------------------------------------
  Name        : Kula Diamond
  Team        : Anti-K' Team
  Nationality : Antarctica
  ----------------------------------------

Enter fighter number (1-5) or 'quit': quit

Exiting the system.

Summary

The read command in shell scripts is a fundamental built-in for reading one line from standard input. Use -p to display a prompt while accepting user input, -s to read passwords and other sensitive input silently, -t to set a timeout, and -n to auto-confirm after a specified number of characters. Specifying multiple variable names splits the input on IFS delimiters and stores each field separately. For reading files line by line, the standard pattern is while IFS= read -r line; do ... done < file, where IFS= prevents whitespace trimming and -r treats backslashes literally. For parsing tab-delimited TSV data, combine IFS=$'\t' with multiple variables. Note that the pipe variant of while read runs in a subshell, so variables updated inside the loop are not accessible in the parent shell. For related idioms, see while / until. For details on IFS and how it interacts with input splitting, see Variables.

If you find any errors or copyright issues, please .