Author’s Note: I’m learning Linux programming as I write this series, so there might be some mistakes or oversimplifications. If you spot any errors, please let me know in the comments! We’re learning together, and I appreciate your feedback.
Introduction
When you’re just starting to write programs in Linux, one of the most important skills to learn is how to make your programs interactive. By “interactive,” I mean programs that can accept input from users as they run. This is a big step up from programs that just do the same thing every time!
Let’s imagine you have a program that checks whether a number is positive or negative. Without interactivity, you’d need to edit the program’s code every time you want to check a different number. That’s not very convenient. Instead, wouldn’t it be better if the program could ask you for a number each time it runs?
That’s exactly what we’re going to learn in this article: how to read keyboard input in Linux so your programs can interact with users.
Basic Keyboard Input in Linux Shell Scripts
The read
Command
The simplest way to get keyboard input in Linux is with the read
command in shell scripts. This built-in command reads a single line of text that the user types.
Here’s a basic example:
#!/bin/bash
echo -n "Please enter your name: "
read name
echo "Hello, $name! Nice to meet you!"
Let’s break down what’s happening:
- We use
echo -n
to print a message asking for input (the-n
means don’t add a new line) - The
read name
command waits for the user to type something and press Enter - Whatever the user typed gets stored in the variable called
name
- We then use that variable to greet the user
When you run this script, it will pause after showing the prompt, waiting for you to type something. After you press Enter, it continues running with your input stored in the variable.
Reading Multiple Values
The read
command can store input in multiple variables at once. For example:
#!/bin/bash
echo -n "Enter your first name and last name: "
read first_name last_name
echo "Your first name is $first_name"
echo "Your last name is $last_name"
When you run this and type “John Smith”, the word “John” gets stored in first_name
and “Smith” gets stored in last_name
. If you type more words, all the extra words get added to the last variable. If you type fewer words, some variables will remain empty.
Using REPLY
for Quick Input
If you don’t specify any variable names with the read
command, Linux puts the input in a special variable called REPLY
:
#!/bin/bash
echo -n "How are you feeling today? "
read
echo "You said that you're feeling: $REPLY"
This is useful for quick scripts where you don’t need to create a new variable name.
Useful Options for the read
Command
The read
command has several helpful options that make it more powerful:
Table: Common read
Command Options
Option | Description | Example |
---|---|---|
-p "prompt" |
Display a prompt before reading input | read -p "Enter your name: " name |
-s |
Silent mode (doesn’t echo characters - useful for passwords) | read -sp "Password: " pass |
-n NUM |
Read only NUM characters | read -n 1 -p "Continue? (y/n) " answer |
-t SECONDS |
Timeout after specified seconds | read -t 5 -p "Quick! " response |
-a ARRAY |
Store input into an array | read -a colors -p "Enter colors: " |
-r |
Raw mode (doesn’t treat backslashes specially) | read -r text |
-e |
Use readline for input editing (command history, etc.) | read -e -p "Edit this: " input |
Showing a Prompt with -p
Instead of using a separate echo
command, you can include a prompt directly:
#!/bin/bash
read -p "What is your favorite color? " color
echo "Ah, $color is a nice color!"
Reading Passwords with -s
When someone is typing sensitive information like a password, you don’t want it showing on the screen:
#!/bin/bash
read -sp "Enter your password: " password
echo # This adds a blank line after input
echo "Your password is ${#password} characters long"
The -s
option makes the input “silent” – the characters don’t appear on screen as the user types.
Setting a Timeout with -t
Sometimes you want to give users a limited time to respond:
#!/bin/bash
if read -t 5 -p "Quick! Enter your name in 5 seconds: " name; then
echo "Hello, $name!"
else
echo "Too slow!"
fi
If the user doesn’t respond within 5 seconds, the script will continue and run the “else” part.
Reading a Specific Number of Characters with -n
You can limit input to a certain number of characters:
#!/bin/bash
read -n 1 -p "Do you want to continue? (y/n) " answer
echo # This adds a blank line after input
if [[ $answer == "y" || $answer == "Y" ]]; then
echo "Continuing..."
else
echo "Stopping."
fi
This script reads just one character (no need to press Enter) and then continues.
Validating User Input
An important part of reading input is making sure it’s valid. Users might type anything – letters when you expect numbers, empty input, or too many values. Good programs check the input before using it.
Checking for Empty Input
#!/bin/bash
read -p "Enter your username: " username
if [[ -z $username ]]; then
echo "Error: Username cannot be empty."
exit 1
fi
echo "Username set to: $username"
The -z
test checks if a string is empty.
Making Sure Input Is a Number
#!/bin/bash
read -p "Enter your age: " age
if [[ ! $age =~ ^[0-9]+$ ]]; then
echo "Error: Age must be a number."
exit 1
fi
echo "Your age is $age"
The =~
operator checks if the input matches a pattern. Here, ^[0-9]+$
is a pattern that matches only numbers.
Understanding IFS (Internal Field Separator)
The IFS (Internal Field Separator) controls how the shell splits input into separate words. By default, IFS contains a space, a tab, and a newline, which means input gets split at these characters.
You can change IFS to split input differently. For example, to read colon-separated data like in the /etc/passwd
file:
#!/bin/bash
echo "Reading user information..."
user_info="john:x:1000:1000:John Smith:/home/john:/bin/bash"
# Save original IFS and set new one
OLD_IFS="$IFS"
IFS=":"
# Read the colon-separated data
read username password uid gid full_name home_dir shell <<< "$user_info"
# Restore original IFS
IFS="$OLD_IFS"
echo "Username: $username"
echo "User ID: $uid"
echo "Full Name: $full_name"
echo "Home Directory: $home_dir"
echo "Shell: $shell"
This changes IFS temporarily to split the input at colons instead of spaces. The <<<
is a “here string” operator that feeds the string to the read command’s input.
Reading Input in C Programs
If you’re writing programs in C rather than shell scripts, you have several ways to read keyboard input.
Table: C Input Functions
Function | Description | Best Used For |
---|---|---|
scanf() |
Reads formatted input | Reading specific data types |
fgets() |
Reads a line of text | Reading entire lines including spaces |
getchar() |
Reads a single character | Character-by-character input |
gets() |
Reads a line (unsafe - avoid using) | Never - it can cause buffer overflows |
Basic Input with scanf()
The simplest method is using the scanf()
function:
#include <stdio.h>
int main() {
char name[50];
int age;
("Enter your name: ");
printf("%s", name);
scanf
("Enter your age: ");
printf("%d", &age);
scanf
("Hello, %s! You are %d years old.\n", name, age);
printf
return 0;
}
This program asks for a name and age, then displays them. Note that scanf()
has some limitations – it stops reading at the first space character, so it can’t handle full names with spaces.
Reading Whole Lines with fgets()
For reading complete lines including spaces, use fgets()
:
#include <stdio.h>
#include <string.h>
int main() {
char full_name[100];
("Enter your full name: ");
printf(full_name, sizeof(full_name), stdin);
fgets
// Remove the newline character that fgets keeps
[strcspn(full_name, "\n")] = '\0';
full_name
("Hello, %s!\n", full_name);
printf
return 0;
}
Getting Single Characters with getchar()
To read a single character at a time:
#include <stdio.h>
int main() {
("Press any key (q to quit): ");
printf
char c;
while ((c = getchar()) != 'q') {
("You pressed: %c\n", c);
printf("Press any key (q to quit): ");
printf}
("Goodbye!\n");
printfreturn 0;
}
Your Turn!
Let’s practice what we’ve learned by creating a simple calculator program that reads two numbers and an operation:
#!/bin/bash
echo "Simple Calculator"
echo "----------------"
read -p "Enter first number: " num1
read -p "Enter second number: " num2
read -p "Enter operation (+, -, *, /): " op
# Validate that inputs are numbers
if [[ ! $num1 =~ ^-?[0-9]+$ ]] || [[ ! $num2 =~ ^-?[0-9]+$ ]]; then
echo "Error: Please enter valid numbers."
exit 1
fi
# Perform calculation based on operation
case $op in
+)
result=$((num1 + num2))
;;
-)
result=$((num1 - num2))
;;
*)
result=$((num1 * num2))
;;
/)
if [ $num2 -eq 0 ]; then
echo "Error: Cannot divide by zero."
exit 1
fi
result=$((num1 / num2))
;;
*)
echo "Error: Invalid operation. Use +, -, *, or /."
exit 1
;;
esac
echo "$num1 $op $num2 = $result"
See Solution
To use this calculator:
- Save the code to a file named
calculator.sh
- Make it executable:
chmod +x calculator.sh
- Run it:
./calculator.sh
- Enter two numbers and an operation when prompted
Key Takeaways
- The
read
command is the main way to get keyboard input in shell scripts - You can read multiple values at once with a single
read
command - The
-p
option lets you show a prompt - The
-s
option hides input (great for passwords) - Always validate user input to make sure it’s what your program expects
- Menus are a user-friendly way to offer multiple options
- C programs can read input using functions like
scanf()
,fgets()
, andgetchar()
Conclusion
Reading keyboard input is an essential skill for creating interactive Linux programs. Whether you’re writing shell scripts or C programs, you now know the basic tools for getting user input and making your programs more flexible and user-friendly.
As you continue learning Linux programming, practice these techniques by adding interactive features to your programs. Start by converting some of your existing scripts to ask for input instead of having values hardcoded. Before long, you’ll be creating fully interactive applications that can respond to whatever the user needs!
References
- GNU Bash Reference Manual - Bash Builtins
- The Linux Command Line by William Shotts
- Linux Input Subsystem Documentation
- GNU C Library Manual - I/O on Streams
- Advanced Bash-Scripting Guide - Interactive Scripts
- The Linux Programming Interface
- Unix & Linux Stack Exchange - read + bash
- C Programming - File I/O Tutorial
FAQ
What’s the difference between read
and echo
?
echo
sends output to the screen, while read
gets input from the keyboard. They’re often used together – echo
to ask a question, then read
to get the answer.
Can I limit what characters a user can type?
The read
command itself doesn’t restrict input, but you can validate what was typed after the fact using patterns and conditionals.
How do I handle passwords securely?
Use read -s
to hide the input as it’s typed. For real security, avoid storing passwords in plain text variables.
What happens if a user enters too much text?
With read
, extra text gets stored (potentially truncated depending on your system’s limits). With C’s scanf()
or fgets()
, you need to specify buffer sizes to prevent overflow.
Can I read input from files instead of the keyboard?
Yes! The same commands can read from files using redirection. For example: read line < myfile.txt
reads the first line from the file.
Happy Coding! 🚀
You can connect with me at any one of the below:
Telegram Channel here: https://t.me/steveondata
LinkedIn Network here: https://www.linkedin.com/in/spsanderson/
Mastadon Social here: https://mstdn.social/@stevensanderson
RStats Network here: https://rstats.me/@spsanderson
GitHub Network here: https://github.com/spsanderson
Bluesky Network here: https://bsky.app/profile/spsanderson.com
My Book: Extending Excel with Python and R here: https://packt.link/oTyZJ
You.com Referral Link: https://you.com/join/EHSLDTL6