How to Read From Pipe in Bash [5 Cases]

LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now

Reading input interactively from the commands pipe is a common task in Bash scripting. In the case of collecting user data, processing commands, or building interactive scripts, understanding how to read from Bash piping is essential. Bash provides different ways to read input from another command using pipe. In this tutorial, I will discuss the basics of pipe, and how you can use it to read input.

What is Piping?

Piping refers to the process of sending the output (usually text) of one program or command as input to another program or command. This allows for the chaining of commands together, creating a pipeline where the output of one process becomes the input of the next process. In Unix-like operating systems, including Linux and macOS, piping is a fundamental feature of the command-line interface (CLI) and is used to perform a wide range of tasks efficiently by combining simple commands. Piping is represented using the vertical bar symbol “|”.

How Does Piping Work?

Actually, piping passes the output of a command (stdout) as the input of another command (stdin). Here’s an example to illustrate how piping works in practice:

cat myfile.txt | grep "keyword" | sort | uniq
IN THIS COMMAND
  • cat myfile.txt: Reads the contents of myfile.txt and sends it to stdout.
  • grep “keyword”: Searches for lines containing “keyword” in the input received from the previous command.
  • sort: Sorts the lines of text alphabetically.
  • uniq: Removes duplicate lines from the sorted input.

Pipes are unidirectional. As a result, the input for the next command is redirected from the output of the previous command, and so on. This allows you to chain multiple commands together to perform more complex data processing tasks efficiently.

5 Cases of How to Read From Pipe in Bash

In Bash, you can read from a pipe using various methods depending on your specific use case. Also, through piping, you can operate many more command-line operations. In this tutorial, I’ll show you five common ways to read data from a pipe.

1. Using the “read” Command in a “while” Loop

You can use the read command with a while loop to read from a pipe within a bash script. The read commands read a line from the input and assign it to a variable.

Now, follow the below steps to learn how to use the read command to read form pipe in Bash:

#!/bin/bash 

cat names.txt | while read name; do 
echo "$name" 
done
EXPLANATION

Here, the cat names.txt redirects the contents of the names.txt file to a while loop through a pipe. This while loop reads each line of input from the previous cat command, and for each line, it assigns the line to the name variable. Finally, echo "$name" uses the echo command to print the value of the name variable to the terminal.

You can preview the content of names.txt if you want by the command:

cat names.txt

Previewing names.txt by cat command

Running the script with ./shownames.sh will show the following output:

Executing showname.sh scriptIt takes the file names.txt as input and passes the content of the file line by line to while loop through the pipe and then echoes each line to the terminal.

2. Using the “read” Command in Terminal

You can use the read command to read from a pipe within a script in the terminal. The read command reads a line from stdin and assigns it to a variable. For example,

echo “Hello LinuxSimply”  | { read name; echo “msg=$name”; }

EXPLANATION
Here, the echo command outputs the string Hello LinuxSimply, and the pipe operator ( | ) sends the output as input for the next command, where the read command reads input from the pipe and assigns it to the variable name. Finally, the echo command echoes the variable value.

Read from pipe to name variableFrom the above image, you can see the read command successfully reads from piped output & later the value is displayed.

Again, if you want to separate the input into multiple pieces and read each of them to variable through the pipe, you can use IFS(Internal Field Separator). Check the process using the following commands:

IFS="-" 
echo "Hello-world!" | (read var1 var2; echo $var1; echo $var2)
EXPLANATION

IFS is a special variable in Bash that specifies the characters used to separate fields or words when splitting strings. In the above command, I set the value of the IFS variable to a hyphen (“-“). Then, echo redirects the string “Hello-LinuxSimply” to the read command through a pipe. Read command splits the input from the pipe into two parts based on the hyphen (as defined by the IFS). The first part is assigned to the variable var1, and the second part is assigned to var2. Finally, echo prints the two variables.

Read from pipe of echo command IFS by hyphenThe output shows that the input Hello-LinuxSimply is separated by a hyphen (-) and stored Hello in var1 and LinuxSimply in var2.

3. Using Function

In Bash, you can pipe the output of a command to a function using process substitution. Process substitution allows you to treat the output of a command as if it were a file, which you can then pass as an argument to a function.

Now, to read from a pipe to a function, check the script:

#!/bin/bash 

function read_stdin() 
{ 
cat > file.txt 
} 
read_stdin
EXPLANATION

The script contains a function named read_stdin(). After that, inside the code block { cat > file.txt; }, the cat command reads input from the standard input (stdin), and the output is redirected to a file named file.txt using the > operator. Finally, after defining the function, read_stdin calls the defined function.

At this stage, let’s pass the output of the date command to this script:

date | ./func.sh

This should write the output of the date command into a file called file.txt. Run the below command to preview it:

cat file.txt

Read date command from pipeHowever, the function doesn’t need an argument or variable declared to accept or hold standard input. It is automatically passed from the command line and inherited from the parent process into the function. Run the below script to read a string passed through a pipe using the function:

#!/bin/bash 

# Define a function that processes input 
my_function() { 
   while IFS= read -r line; do 
   #Your processing logic here 
    echo "Processed: $line" 
    done 
    } 

# Pipe the output of a command to the function 
echo "Hello, LinuxSimply" | my_function
EXPLANATION

The script contains a function named my_function(). After that, the while IFS= read -r line; reads lines from a file or input stream line by line. Inside the block do … done I used echo "Processed: $line" as an example command that processes input. You can replace the processing logic inside this function with your own. Finally, I piped the output of the echo command to my_function using ‘|’.

Executing func2.sh scriptThe image prints the string passed to the func2.sh script indicates that it successfully read the string passed to it through the pipe.

4. Using Lastpipe Feature

When you use piping with read to assign a value to a variable, the shell creates a new sub-shell where the piped command is executed. Therefore, the value is lost. So, the variable cannot be used. However, when we use the lastpipe option in the recent versions of bash, we can pipe the output of a command, such as echo, to read. The read statement will then assign the output to a variable.

Using the lastpipe feature, the last command is executed in the current shell instead of a new sub-shell. For that reason, the environment retains its value. By default, this option is disabled. Use the below command to enable it.

shopt -s lastpipe 
set +m
EXPLANATION
  • shopt: Shopt (shell option) is a Bash built-in command used to manipulate shell options.
  • -s: The –s option is used with shopt to set (enable) a shell option.
  • lastpipe: lastpipe is the name of the shell option that changes the behavior of the last command in a pipeline.
  • set +m: Run a command in the background but not actively report its status.

Now, to test the lastpipe, let’s use a command with a pipe.

cal -A1 | read month

This command passes the output of cal command to month variable through a pipe and the variable reads the first line of the cal output.

echo “$month”

Enabling lastpipe and read from pipe of cal command to month variableAfter configuring the shell for lastpipe, month variable read the output of cal -A1 command through pipe.

5. Using Command Substitution

Command substitution in Bash allows you to capture the output of a command or a pipeline and use it as an input or argument to another command. For example, you can create a Bash script that counts the number of lines in a text file provided to it through pipe.

Check the script below to know how to read from pipe with the command substitution approach:

#!/bin/bash 

#Read input from a pipe 
input_data=$(cat -) 

#count the line number 
line_count=$(echo "$input_data" | wc -l) 

#Print the result 
echo "The number of lines is : $line_count"
EXPLANATION

The $(cat -) captures the input data from pipe and echo "$input_data" | wc -l counts the number of lines by the wc command in the input_data variable. Finally, the echo command prints the number of lines in the input.

First, preview the content of names.txt.

cat names.txt

Now run the following command:

cat names.txt | ./count_lines.sh

This will pass the contents of names.txt through the pipe to count_lines.sh. Then the script will count and print the number of lines in it. The output will be as below:Read file from pipe and count lines in it The output image shows the number of lines in the names.txt file.

Conclusion

Reading from piping in bash is a powerful technique in Unix-like systems, enabling the creation of complex pipelines using simple, modular commands. As piping allows you to chain multiple commands together to perform more complex data processing tasks efficiently, reading from piping can be a vital and fundamental concept for text processing and automation on the command line.

People Also Ask

How to use pipe in Bash script?

In Bash, the pipe operator (|) is used to create a ‘pipeline’ between commands. It takes the standard output (stdout) of the command to the left and pipes it as the standard input (stdin) to the command on the right. The basic syntax is: command_one | command_two.

How to read a value in Bash?

To read a value in Bash. you can use the read command that takes the user input and splits the string into fields, assigning each new word to an argument. A common example of reading value with read command is echo “Hello World”  | { read name; echo “msg=$name”; }. This will read the value from echo and pass it into the variable name.

How can I read line by line from a variable in Bash?

You can use a while loop to read line by line from a variable in Bash. Let’s say you have a variable called data that stores multiple lines. Follow the script to read the lines one by one from a variable data:

while IFS= read -r line; do
    echo "Line: $line"
done <<< "$data" 

How to read input from file in Bash?

Let’s say you have a file called data.txt. To read input from a file in Bash, use this line in your script input_data=$(cat -). Then add your own processing logic. For example, if a Bash script (mybash.sh) contains the scripts:

input_data=$(cat -)
echo $input_data

Then executing the command cat data.txt | ./mybash.sh will read the file data.txt and print it in the terminal.


Related Articles


<< Go Back to Bash Piping | Bash Redirection and Piping | Bash Scripting Tutorial

4.8/5 - (13 votes)
Ashikur Rahman

Hello, I’m Ashikur Rahman, currently working as a Linux Content Developer Executive at SOFTEKO. I have completed my graduation in Computer Science and Engineering from Khulna University of Engineering & Technology (KUET). Also, I’m pursuing my master’s in the same department at Bangladesh University of Engineering & Technology (BUET). I like to learn new technologies, contribute, and share those with others. Here my goal is to provide beneficial and user-friendly articles on Linux distribution for everyone. Read Full Bio

Leave a Comment