Linux Bash: Language Basics

stdin, stdout and stderr

Bash creates stdin, stdout and stderr streams for each command in the terminal. These streams carry text as data.

In Linux, almost all the streams are treated as if they were files. Just like you can read/write a file, you can read/write a data from these streams.

stdin: Stands for standard input. It takes text as input.
stdout: Stands for standard output. The text output of a command is stored in the stdout stream.
stderr: Stands for standard error. Whenever a command faces an error, the error message is stored in this stream.

Each stream has file descriptor ID as below

  • stdin – /dev/stdin or /dev/fd/0
  • stdout – /dev/stdout or /dev/fd/1
  • stderr – /dev/stderr or /dev/fd/2

Stdin example

read command require input from the keyboard.

When no argument is provided to read command, the entire line is assigned to the REPLY variable. So, we can print REPLY variable in terminal as below.

$ read
Hello World

$ echo $REPLY
Hello World

Stdout example

Output of echo command is written to terminal or stdout

$ echo "Hello World"
Hello World

Piping Streams

The | sign is responsible for piping the stdout stream of a command to the stdin stream of next command.

The |& sign is responsible for piping both stdout and stderr streams of a command to the stdin stream of next command.

Piping stream is a form of redirection. It only redirect stdin, stdout and stderr streams.

$ echo "Hello World" | grep Hello
Hello World

The output of echo command is written in the stdout stream, then the piping redirects the content of stdout to stdin for the grep command. That's how grep command knows what content to perform the operation on.

If you want to pipe both the stdout and stderr to the next command, then use the I& instead of I

$ anything |& cat
zsh: command not found: anything

Redirecting Streams

The > sign is responsible for redirecting the stdout stream of a command to a file stream.

The >> sign is responsible for appending the stdout stream of a command to a file stream.

The < sign is responsible for redirecting the file stream to a stdin stream of a command.

The << sign is responsible for redirecting the multi-line string to a stdin stream of a command. It is also known as here-document.

The <<< sign is responsible for redirecting the single string to a stdin stream of a command. It is also known as here-string.

The >& sign is responsible for redirecting and merging both stdout and stderr streams of a command to the file stream.

Redirecting stream is similar to Piping stream but it is used for file stream to stdin or stdout streams.

Redirecting stdout stream of a command to file stream

$ echo "Hello World" > hello.txt

or

$ echo "Hello World" 1> hello.txt

Redirecting stderr stream to file stream

$ something 2> error.txt

/dev/null is a special file which ignores anything put into it.

$ something 2> /dev/null

Appending stdout stream of a command to file stream

$ echo "How is the weather today?" >> hello.txt

or

$ echo "How is the weather today?" 1>> hello.txt

Redirecting file stream to stdin stream of a command

$ cat < hello.txt
Hello World

or

$ echo "Hello World" | cat
Hello World

Redirecting file stream to stdin stream of a command as parameter

$ cat > input.txt <<EOL
kenan
kenanhancer@gmail.com
EOL
$ cat > greeting.sh <<EOL
#!/bin/bash

echo "Enter name"
read name

echo "Enter email"
read email

echo "Your name is $name and email is $email"
EOL
$ . ./greeting.sh < input.txt
Enter name
Enter email
Your name is kenan and email is kenanhancer@gmail.com

Redirecting file stream to stdin stream of a command as parameter and redirecting stdout stream of command to file stream.

$ . ./greeting.sh < input.txt > greetingOutput.txt
$ cat greetingOutput.txt
Enter name
Enter email
Your name is kenan and email is kenanhancer@gmail.com

Redirecting stderr and stdout streams to separate file streams

$ echo “hello world” 1> output.txt 2> debug.txt

Some examples

$ ls -l > output.txt
$ wc -l countries.txt > output.txt
$ ls -l >> output.txt
$ wc -l < countries.txt
$ wc -l < countries.txt > output.txt
$ ls -l blabla 2> error.log
$ ls -l blabla >& outputOrError.txt

or

Redirecting stdout stream to file stream and stderr stream to file stream. We redirect to a file stream first then redirect the error stream.

$ ls -l blabla > outputOrError.txt 2>&1
$ ls | head -3 | tail -1 > output.txt

Command Substitution

Command substitution is shown as $() sign.

$ NOW=$(date)
$ echo $NOW
Sun 19 Jun 2022 16:57:16 BST

or

$ echo $(date)
Sun 19 Jun 2022 16:57:16 BST
$ echo "Date is $(date)"
Date is Sun 19 Jun 2022 16:58:02 BST
$ cat <<< "Date is $(date)"
Date is Sun 19 Jun 2022 16:58:02 BST
$ cat <<< $(echo "Date is $(date)")
Date is Sun 19 Jun 2022 16:58:02 BST
$ echo "Date is $(date)" | cat
Date is Sun 19 Jun 2022 16:58:02 BST

Process Substitution

Process substitution is shown as <() sign. Process Substitution writes output in a file and returns that file name.

$ cat <(date)
Sun 19 Jun 2022 16:58:02 BST
$ cat < <(date)
Sun 19 Jun 2022 16:58:02 BST
$ date | cat
Sun 19 Jun 2022 16:58:02 BST
$ echo $(date) | cat
Sun 19 Jun 2022 16:58:02 BST
This entry was posted in Bash.

Leave a Reply

Your email address will not be published.