|

Linux CLI 56 🐧 shell scripts input text

56 – shell scripts input text

#!/bin/bash

echo "Enter your name:"
read name
echo "Hello, $name!"

echo "Enter first name and last name separated by a space:"
read fname lname
echo "Hello, $fname $lname!"

read -p "Please enter your age: " age
echo "You are $age years old."

read -s -p "Enter your password: " password
echo
echo "Password entered: $password"

read -n 1 -p "Press any key to continue..." response
echo
echo "You pressed: $response"

if read -t 5 -p "Enter your name within 5 seconds: " name; then
    echo "Hello, $name!"
else
    echo "No input received in time."
fi

The read command is how a shell script asks the user for input. It reads a line from standard input (usually the keyboard), splits it into fields, and assigns them to variables. With a few options, it can prompt, hide input, read a fixed number of characters, or time out.

Key point: read reads one line at a time and splits it on IFS (internal field separator — space, tab, newline by default). The number of variables determines how many fields are captured; the last variable gets the rest of the line.


a – read command in shell scripts

read is used to accept input from the user. It reads one line from standard input (usually the keyboard) and assigns it to one or more variables.

Syntax:

read [options] [variable...]

Common options:

OptionPurpose
-p PROMPTDisplay a custom prompt
-n NRead exactly N characters
-N NRead exactly N characters (ignore delimiter)
-d CHARUse a different delimiter
-sSilent input (for passwords)
-t NTimeout after N seconds
-rRaw mode — don’t interpret backslashes
-a ARRAYRead into an array
-eUse readline (line editing)
-i TEXTInitial text for readline

Basic usage — read into one variable:

$ read name
Alice
$ echo "Hello, $name!"
[ Hello, Alice! ]

read waits for you to type a line and press Enter. The whole line (minus the newline) goes into name.

Reading multiple variables:

$ read fname lname
Alice Smith
$ echo "Hello, $fname $lname!"
[ Hello, Alice Smith! ]

The line is split on whitespace. fname gets Alice, lname gets Smith.

$ read a b c
one two three four five
$ echo "a=$a b=$b c=$c"
[ a=one b=two c=three four five ]

When there are more fields than variables, the last variable gets the rest.

Reading into an array:

$ read -a fruits
apple banana cherry
$ echo "${fruits[0]}"
[ apple ]
$ echo "${fruits[@]}"
[ apple banana cherry ]
$ echo "${#fruits[@]}"
[ 3 ]

The -p option — custom prompt:

$ read -p "Please enter your age: " age
Please enter your age: 30
$ echo "You are $age years old."
[ You are 30 years old. ]

The prompt is printed to stderr, so it doesn’t interfere with piped output.

The -s option — silent input (passwords):

$ read -s -p "Enter your password: " password
Enter your password:
$ echo
$ echo "Password entered: $password"
[ Password entered: secret123 ]

With -s, the characters you type are not echoed to the terminal. You need to print a newline yourself afterward with echo.

The -n option — read N characters:

$ read -n 1 -p "Press any key to continue..." response
Press any key to continue...y
$ echo
$ echo "You pressed: $response"
[ You pressed: y ]

-n 1 reads a single character without waiting for Enter. Useful for “Press any key” prompts.

The -t option — timeout:

$ if read -t 5 -p "Enter your name within 5 seconds: " name; then
>     echo "Hello, $name!"
> else
>     echo "No input received in time."
> fi
Enter your name within 5 seconds: Alice
[ Hello, Alice! ]

If the user doesn’t type anything within 5 seconds, read returns a non-zero exit status and the else branch runs.

$ if read -t 5 -p "Enter your name within 5 seconds: " name; then
>     echo "Hello, $name!"
> else
>     echo "No input received in time."
> fi
Enter your name within 5 seconds:
[ No input received in time. ]

The -r option — raw mode:

Without -r, backslashes are interpreted as escape characters:

$ read path
C:\Users\Alice
$ echo "$path"
[ C:UsersAlice ]              # backslashes eaten

$ read -r path
C:\Users\Alice
$ echo "$path"
[ C:\Users\Alice ]            # preserved

Best practice: Almost always use read -r. It prevents surprising backslash behavior.

The -d option — custom delimiter:

$ read -d ':' part
hello:world
$ echo "$part"
[ hello ]

-d ':' makes read stop at the colon instead of the newline.

Reading from a file or pipe:

# Read a file line by line
$ while read -r line; do
>     echo "Line: $line"
> done < file.txt

# Read from a pipe
$ cat file.txt | while read -r line; do
>     echo "Line: $line"
> done

Reading with a default value:

$ read -p "Name [Guest]: " name
$ name="${name:-Guest}"
$ echo "Hello, $name"

Reading multiple lines:

$ read -p "Line 1: " line1
$ read -p "Line 2: " line2
$ echo "$line1 / $line2"

Common read pitfalls:

PitfallProblemSolution
No -rBackslashes eatenUse read -r
Whitespace trimmedLeading/trailing spaces lostSet IFS=
Loop in pipeVariables lost after loopUse process substitution
read in subshellCan’t set outer varsUse while read with redirect
No promptUser doesn’t know what to typeUse -p

Preserving whitespace with IFS=:

$ read line
   hello world
$ echo "[$line]"
[ hello world ]

$ IFS= read -r line
   hello world
$ echo "[$line]"
[    hello world ]

Setting IFS= (empty) disables field splitting, so the whole line — including leading/trailing whitespace — is preserved.


b – read command examples

Here are the practical examples you’ll use most.

1. Basic input:

#!/bin/bash
echo "Enter your name:"
read name
echo "Hello, $name!"
$ ./script.sh
Enter your name:
Alice
[ Hello, Alice! ]

2. Multiple variables:

#!/bin/bash
echo "Enter first name and last name separated by a space:"
read fname lname
echo "Hello, $fname $lname!"
$ ./script.sh
Enter first name and last name separated by a space:
Alice Smith
[ Hello, Alice Smith! ]

3. Custom prompt with -p:

#!/bin/bash
read -p "Please enter your age: " age
echo "You are $age years old."
$ ./script.sh
Please enter your age: 30
[ You are 30 years old. ]

4. Silent input with -s:

#!/bin/bash
read -s -p "Enter your password: " password
echo
echo "Password entered: $password"
$ ./script.sh
Enter your password:
[ Password entered: secret123 ]

5. Read exactly N characters with -n:

#!/bin/bash
read -n 1 -p "Press any key to continue..." response
echo
echo "You pressed: $response"
$ ./script.sh
Press any key to continue...y
[ You pressed: y ]

6. Timeout with -t:

#!/bin/bash
if read -t 5 -p "Enter your name within 5 seconds: " name; then
    echo "Hello, $name!"
else
    echo "No input received in time."
fi
$ ./script.sh
Enter your name within 5 seconds: Alice
[ Hello, Alice! ]

$ ./script.sh
Enter your name within 5 seconds:
[ No input received in time. ]

More examples:

# Read into an array
read -a colors
echo "First color: ${colors[0]}"
echo "All colors: ${colors[@]}"
echo "Count: ${#colors[@]}"

# Read with a default
read -p "Name [Guest]: " name
name="${name:-Guest}"
echo "Hello, $name"

# Read a password twice and compare
read -s -p "Password: " p1; echo
read -s -p "Confirm: " p2; echo
if [ "$p1" = "$p2" ]; then
    echo "Passwords match"
else
    echo "Passwords do not match"
fi

# Read a line from a file
while IFS= read -r line; do
    echo "Line: $line"
done < file.txt

# Read from a pipe
cat file.txt | while IFS= read -r line; do
    echo "Line: $line"
done

# Read until a specific character
read -d ';' -p "Enter data (end with ;): " data
echo "You entered: $data"

# Read with a timeout and fallback
if read -t 3 -p "Continue? (y/n): " answer; then
    echo "You chose: $answer"
else
    echo "Timeout — defaulting to no"
    answer="n"
fi

# Read a menu choice
read -p "Choose [1-3]: " choice
case "$choice" in
    1) echo "Option 1" ;;
    2) echo "Option 2" ;;
    3) echo "Option 3" ;;
    *) echo "Invalid" ;;
esac

# Read multiple values on one line
read -p "Enter name and age: " name age
echo "Name: $name, Age: $age"

# Read with a hidden password and validate length
read -s -p "Password (min 8 chars): " pw; echo
if [ ${#pw} -lt 8 ]; then
    echo "Too short"
fi

# Read a filename and check if it exists
read -p "Enter a filename: " file
if [ -f "$file" ]; then
    echo "File exists"
else
    echo "File not found"
fi

# Read lines until EOF
while IFS= read -r line; do
    echo "Got: $line"
done
# Press Ctrl+D to end

# Read with a prompt and default
read -p "Enter port [8080]: " port
port="${port:-8080}"
echo "Using port $port"

# Read and validate numeric input
read -p "Enter a number: " num
if [[ "$num" =~ ^[0-9]+$ ]]; then
    echo "Valid number: $num"
else
    echo "Not a number"
fi

Complete Example Session

# ============================================
# PART 1: BASIC INPUT
# ============================================

$ read name
Alice
$ echo "Hello, $name!"
[ Hello, Alice! ]

# ============================================
# PART 2: MULTIPLE VARIABLES
# ============================================

$ read fname lname
Alice Smith
$ echo "Hello, $fname $lname!"
[ Hello, Alice Smith! ]

$ read a b c
one two three four five
$ echo "a=$a b=$b c=$c"
[ a=one b=two c=three four five ]

# ============================================
# PART 3: CUSTOM PROMPT
# ============================================

$ read -p "Please enter your age: " age
Please enter your age: 30
$ echo "You are $age years old."
[ You are 30 years old. ]

# ============================================
# PART 4: SILENT INPUT
# ============================================

$ read -s -p "Enter your password: " password
Enter your password:
$ echo
$ echo "Password entered: $password"
[ Password entered: secret123 ]

# ============================================
# PART 5: SINGLE CHARACTER
# ============================================

$ read -n 1 -p "Press any key to continue..." response
Press any key to continue...y
$ echo
$ echo "You pressed: $response"
[ You pressed: y ]

# ============================================
# PART 6: TIMEOUT
# ============================================

$ if read -t 5 -p "Enter your name within 5 seconds: " name; then
>     echo "Hello, $name!"
> else
>     echo "No input received in time."
> fi
Enter your name within 5 seconds: Alice
[ Hello, Alice! ]

$ if read -t 5 -p "Enter your name within 5 seconds: " name; then
>     echo "Hello, $name!"
> else
>     echo "No input received in time."
> fi
Enter your name within 5 seconds:
[ No input received in time. ]

# ============================================
# PART 7: READ INTO AN ARRAY
# ============================================

$ read -a fruits
apple banana cherry
$ echo "${fruits[0]}"
[ apple ]
$ echo "${fruits[@]}"
[ apple banana cherry ]
$ echo "${#fruits[@]}"
[ 3 ]

# ============================================
# PART 8: RAW MODE
# ============================================

$ read path
C:\Users\Alice
$ echo "$path"
[ C:UsersAlice ]

$ read -r path
C:\Users\Alice
$ echo "$path"
[ C:\Users\Alice ]

# ============================================
# PART 9: CUSTOM DELIMITER
# ============================================

$ read -d ':' part
hello:world
$ echo "$part"
[ hello ]

# ============================================
# PART 10: READING A FILE
# ============================================

$ cat > names.txt << EOF
Alice
Bob
Charlie
EOF

$ while IFS= read -r line; do
>     echo "Name: $line"
> done < names.txt
[ Name: Alice ]
[ Name: Bob ]
[ Name: Charlie ]

# ============================================
# PART 11: PRESERVING WHITESPACE
# ============================================

$ read line
   hello world
$ echo "[$line]"
[ hello world ]

$ IFS= read -r line
   hello world
$ echo "[$line]"
[    hello world ]

# ============================================
# PART 12: DEFAULT VALUE
# ============================================

$ read -p "Name [Guest]: " name
$ name="${name:-Guest}"
$ echo "Hello, $name"
[ Hello, Guest ]

Quick Reference

read — Options

OptionPurpose
-p PROMPTCustom prompt
-n NRead N characters
-N NRead N chars, ignore delimiter
-d CHARCustom delimiter
-sSilent (password)
-t NTimeout after N seconds
-rRaw — no backslash interpretation
-a ARRAYRead into array
-eUse readline
-i TEXTInitial text

read — Common Patterns

PatternPurpose
read nameBasic input
read a b cMultiple variables
read -a arrInto an array
read -p "Prompt: " varWith prompt
read -s -p "Pass: " pwHidden input
read -n 1 -p "Key: " kSingle char
read -t 5 -p "..." xTimeout
read -r lineRaw mode
IFS= read -r linePreserve whitespace
read -d ':' xCustom delimiter
while read -r line; do ...; done < fileRead file line by line

read — Variables

VariableMeaning
$REPLYDefault variable if none given
$IFSField separator
${#var}Length of input
$?Exit status of read

read — Exit Codes

CodeMeaning
0Input read successfully
>0Timeout or EOF

Related Commands

CommandPurpose
readRead from stdin
echoOutput
printfFormatted output
catRead files
mapfileRead lines into array

Best Practices

Do This:

# Use -r to preserve backslashes
read -r line                          # ✅

# Use -p for prompts
read -p "Name: " name                 # ✅

# Use -s for passwords
read -s -p "Password: " pw            # ✅

# Use IFS= to preserve whitespace
IFS= read -r line                     # ✅

# Use -t for timeouts
read -t 5 -p "Quick: " x              # ✅

# Provide defaults
read -p "Name [Guest]: " name
name="${name:-Guest}"                 # ✅

# Validate input
if [[ "$num" =~ ^[0-9]+$ ]]; then
    ...
fi                                    # ✅

# Use -a for arrays
read -a items                         # ✅

# Read files with while loop
while IFS= read -r line; do
    ...
done < file.txt                       # ✅

Don’t Do This:

# Don't forget -r
read path                             # ❌ backslashes eaten

# Don't read passwords without -s
read -p "Password: " pw               # ❌ visible on screen

# Don't forget the newline after -s
read -s -p "Password: " pw            # ❌ prompt on same line
echo                                  # ✅ add this

# Don't read from a pipe and expect outer vars
cat file | while read line; do
    LAST="$line"
done
echo "$LAST"                          # ❌ subshell — empty

# Don't use read without a prompt
read                                  # ⚠️  user confused

# Don't skip validation
read -p "Age: " age
echo "Next year: $((age + 1))"        # ❌ if age isn't numeric

# Don't forget IFS= when whitespace matters
read line                             # ❌ trims leading/trailing

Common Pitfalls

PitfallProblemSolution
No -rBackslashes eatenUse read -r
Whitespace trimmedLeading/trailing lostIFS= read -r
Password visibleSecurity leakUse -s
No promptUser doesn’t knowUse -p
Subshell variable lossCan’t set outer varUse process substitution
No timeoutScript hangsUse -t
No validationBad input crashesCheck with regex
Missing newline after -sPrompt runs into outputAdd echo

Real-World Examples

1. Simple Name Prompt

#!/bin/bash
read -p "Enter your name: " name
echo "Hello, $name!"
[ Enter your name: Alice ]
[ Hello, Alice! ]

2. Two-Part Name

#!/bin/bash
read -p "Enter first and last name: " fname lname
echo "Hello, $fname $lname!"
[ Enter first and last name: Alice Smith ]
[ Hello, Alice Smith! ]

3. Password Input

#!/bin/bash
read -s -p "Password: " pw
echo
read -s -p "Confirm: " pw2
echo
if [ "$pw" = "$pw2" ]; then
    echo "Passwords match"
else
    echo "Passwords do not match"
fi
[ Password: ]
[ Confirm: ]
[ Passwords match ]

4. Press Any Key

#!/bin/bash
read -n 1 -p "Press any key to continue..." key
echo
echo "Continuing..."
[ Press any key to continue... ]
[ Continuing... ]

5. Timed Input

#!/bin/bash
if read -t 5 -p "Quick! Name: " name; then
    echo "Hello, $name"
else
    echo "Too slow!"
fi
[ Quick! Name: Alice ]
[ Hello, Alice ]

6. Menu Selection

#!/bin/bash
echo "1) Start"
echo "2) Stop"
echo "3) Quit"
read -p "Choice: " choice
case "$choice" in
    1) echo "Starting..." ;;
    2) echo "Stopping..." ;;
    3) exit 0 ;;
    *) echo "Invalid choice" ;;
esac

7. Read a File Line by Line

#!/bin/bash
while IFS= read -r line; do
    echo "Line: $line"
done < file.txt

8. Validate Numeric Input

#!/bin/bash
while true; do
    read -p "Enter a number: " num
    if [[ "$num" =~ ^[0-9]+$ ]]; then
        break
    fi
    echo "Not a number. Try again."
done
echo "You entered: $num"

9. Confirm Before Action

#!/bin/bash
read -p "Delete all files? (y/n): " answer
case "$answer" in
    y|Y) echo "Deleting..." ;;
    *) echo "Cancelled" ;;
esac

10. Default Value

#!/bin/bash
read -p "Port [8080]: " port
port="${port:-8080}"
echo "Using port $port"
[ Port [8080]: ]
[ Using port 8080 ]

11. Read a Full Line with Spaces

#!/bin/bash
IFS= read -r -p "Enter a sentence: " sentence
echo "You said: $sentence"

12. Read an Array

#!/bin/bash
read -a items -p "Enter items separated by spaces: "
for item in "${items[@]}"; do
    echo "Item: $item"
done

13. Read Until EOF

#!/bin/bash
echo "Enter text (Ctrl+D to finish):"
while IFS= read -r line; do
    echo "Got: $line"
done

14. Read from a Here String

#!/bin/bash
read -r name <<< "Alice"
echo "Hello, $name"
[ Hello, Alice ]

15. Read a Path with Backslashes

#!/bin/bash
read -r -p "Path: " path
echo "You entered: $path"
[ Path: C:\Users\Alice ]
[ You entered: C:\Users\Alice ]

16. Timeout with Fallback

#!/bin/bash
if read -t 3 -p "Continue? (y/n): " answer; then
    echo "You chose: $answer"
else
    echo "Timeout — defaulting to no"
    answer="n"
fi

17. Read a Password of Minimum Length

#!/bin/bash
while true; do
    read -s -p "Password (min 8): " pw
    echo
    if [ ${#pw} -ge 8 ]; then
        break
    fi
    echo "Too short"
done
echo "Password accepted"

18. Read a Filename and Check

#!/bin/bash
read -p "File: " file
if [ -f "$file" ]; then
    echo "Found: $file"
    wc -l "$file"
else
    echo "Not found"
fi

19. Read Multiple Lines

#!/bin/bash
read -p "Line 1: " l1
read -p "Line 2: " l2
read -p "Line 3: " l3
echo "You entered:"
echo "$l1"
echo "$l2"
echo "$l3"

20. Read with a Prompt Loop

#!/bin/bash
while true; do
    read -p "Command (quit to exit): " cmd
    case "$cmd" in
        quit|exit) break ;;
        date) date ;;
        ls) ls ;;
        *) echo "Unknown: $cmd" ;;
    esac
done

Visual: How read Works

┌──────────────────────────────────────────────┐
│                  read                        │
│                                              │
│  $ read -p "Name: " name                     │
│                                              │
│  ┌────────────────────────────────────────┐  │
│  │  stdin (keyboard)                      │  │
│  │  Alice                                 │  │
│  └────────────────┬───────────────────────┘  │
│                   │                          │
│                   ▼                          │
│  Split on IFS (space, tab, newline)          │
│                   │                          │
│                   ▼                          │
│  Assign to variables:                        │
│    name = "Alice"                            │
│                                              │
└──────────────────────────────────────────────┘

┌──────────────────────────────────────────────┐
│           Multiple variables                 │
│                                              │
│  $ read a b c                                │
│  one two three four five                     │
│                                              │
│  Split: [one] [two] [three] [four] [five]    │
│                                              │
│  a = "one"                                   │
│  b = "two"                                   │
│  c = "three four five"  ← last gets rest     │
│                                              │
└──────────────────────────────────────────────┘

Summary

OptionPurposeExample
read nameBasic inputread name
read a b cMultiple variablesread fname lname
-p PROMPTCustom promptread -p "Age: " age
-sSilent (password)read -s -p "Pass: " pw
-n NRead N charactersread -n 1 -p "Key: " k
-t NTimeout after N secondsread -t 5 -p "..." x
-rRaw moderead -r line
-d CHARCustom delimiterread -d ':' x
-a ARRAYRead into arrayread -a items
IFS= read -rPreserve whitespaceIFS= read -r line
while readRead file line by linewhile read -r l; do ...; done < f

Key takeaways:

  • read accepts input from the user, one line at a time
  • It splits the line on IFS (spaces, tabs, newlines by default)
  • Multiple variables → first fields go to first vars, last var gets the rest
  • -p shows a prompt, -s hides input, -n reads N chars, -t sets a timeout
  • Always use -r — it preserves backslashes
  • Use IFS= read -r to preserve leading/trailing whitespace
  • Use -a to read into an array
  • Use while IFS= read -r line; do ...; done < file to read a file line by line
  • Check $? or use if read ... to detect timeout/EOF
  • Validate input — never trust the user
  • Provide defaults with ${var:-default}

Remember: read is how your script talks to the user. Use -p for prompts, -s for passwords, -t for timeouts, -r for safety. Split into multiple variables for structured input, or use -a for arrays. Read files with while IFS= read -r. And always validate — a script that trusts its input is a script that breaks. Master read, and your scripts become interactive tools instead of one-way commands.


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!