reworking content
All checks were successful
learn org at code.softwareshinobi.com/linux.softwareshinobi.com/pipeline/head This commit looks good
All checks were successful
learn org at code.softwareshinobi.com/linux.softwareshinobi.com/pipeline/head This commit looks good
This commit is contained in:
217
landing/docs/Bash-Scripts/023-bash-redirection.md
Normal file
217
landing/docs/Bash-Scripts/023-bash-redirection.md
Normal file
@@ -0,0 +1,217 @@
|
||||
# Redirection
|
||||
|
||||
Master Bash redirection and pipes. These essential Linux features are critical for efficient system administration. Every command handles input, output, and errors through **File Descriptors (FDs)**:
|
||||
|
||||
* **STDIN** (0): Standard Input – receives data.
|
||||
* **STDOUT** (1): Standard Output – sends regular data.
|
||||
* **STDERR** (2): Standard Error – sends error messages.
|
||||
|
||||
---
|
||||
|
||||
### Pipes vs. Redirection
|
||||
|
||||
Both manage data streams, but with a key difference:
|
||||
* **Redirection** routes a command's input/output to or from a **file**.
|
||||
* **Pipes** (`|`) connect the **output of one command directly to the input of another command**.
|
||||
|
||||
---
|
||||
|
||||
### STDIN (Standard Input)
|
||||
|
||||
Commands often expect input. By default, this is your keyboard, but you can redirect it from other sources.
|
||||
|
||||
**Redirecting from a file (`<`)**:
|
||||
Use `<` to feed a file's content as input to a command. Create `input.txt`:
|
||||
|
||||
```bash
|
||||
touch input.txt
|
||||
```
|
||||
Open `input.txt` and add:
|
||||
```
|
||||
Line 1
|
||||
Line 2
|
||||
```
|
||||
Save `input.txt`.
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
cat < input.txt
|
||||
```
|
||||
This prints `input.txt` content, similar to `cat input.txt`.
|
||||
|
||||
**Here-Documents (`<< DELIMITER`)**:
|
||||
For multi-line input directly in your script or terminal, use a here-document with a custom delimiter (e.g., `EOF`).
|
||||
|
||||
```bash
|
||||
cat << EOF
|
||||
Hello World!
|
||||
How are you?
|
||||
EOF
|
||||
```
|
||||
This will print:
|
||||
```
|
||||
Hello World!
|
||||
How are you?
|
||||
```
|
||||
Similarly, with `wc -l` to count lines:
|
||||
```bash
|
||||
wc -l << EOF
|
||||
Hello World!
|
||||
How are you?
|
||||
EOF
|
||||
```
|
||||
Output:
|
||||
```
|
||||
2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### STDOUT (Standard Output)
|
||||
|
||||
Regular command output typically goes to your terminal. Redirect it to a file.
|
||||
|
||||
**Overwrite (`>`)**:
|
||||
Use `>` to send output to a file. If the file exists, its content is overwritten. Create `file.txt` (or ensure it's empty):
|
||||
|
||||
```bash
|
||||
echo "Hello World!" > file.txt
|
||||
cat file.txt # Output: Hello World!
|
||||
```
|
||||
Running again overwrites:
|
||||
|
||||
```bash
|
||||
echo "How are you?" > file.txt
|
||||
cat file.txt # Output: How are you? (Previous content is gone)
|
||||
```
|
||||
|
||||
**Append (`>>`)**:
|
||||
Use `>>` to add output to the end of a file without overwriting existing content.
|
||||
|
||||
```bash
|
||||
echo "Hello World!" > file.txt # Start fresh
|
||||
echo "How are you?" >> file.txt
|
||||
cat file.txt
|
||||
```
|
||||
Output:
|
||||
```
|
||||
Hello World!
|
||||
How are you?
|
||||
```
|
||||
|
||||
You can also explicitly specify the STDOUT file descriptor (1): `echo "Hello" 1> file.txt`.
|
||||
|
||||
---
|
||||
|
||||
### STDERR (Standard Error)
|
||||
|
||||
Error messages, distinct from standard output, are sent to **STDERR**. Redirect them using file descriptor 2.
|
||||
|
||||
**Redirecting Errors (`2>`)**:
|
||||
Use `2>` to redirect error messages. For example, `ls --invalid-flag` generates an error.
|
||||
|
||||
```bash
|
||||
ls --invalid-flag 2> error.txt
|
||||
cat error.txt # Contains the error message
|
||||
```
|
||||
Use `2>>` to append error messages to a file.
|
||||
|
||||
**Discarding Errors (`2> /dev/null`)**:
|
||||
Send error output to `/dev/null` to completely suppress it. `/dev/null` is a special 'black hole' device that discards all data written to it.
|
||||
|
||||
```bash
|
||||
ls --invalid-flag 2> /dev/null # Error message is hidden
|
||||
```
|
||||
|
||||
**Redirecting Both STDOUT and STDERR**:
|
||||
You can manage both streams simultaneously.
|
||||
|
||||
To separate regular output and errors into different files:
|
||||
|
||||
```bash
|
||||
# Assuming 'install_package.sh' generates both output and errors
|
||||
./install_package.sh > output.txt 2> error.txt
|
||||
```
|
||||
|
||||
To send both to the same file (concise syntax):
|
||||
|
||||
```bash
|
||||
./install_package.sh > combined_output.txt 2>&1
|
||||
```
|
||||
The `2>&1` redirects file descriptor 2 (STDERR) to the same location as file descriptor 1 (STDOUT), which is `combined_output.txt`. Alternatively, an even shorter Bash 4+ syntax: `&> combined_output.txt`.
|
||||
|
||||
---
|
||||
|
||||
### Piping (`|`)
|
||||
|
||||
Pipes connect the standard output of one command directly to the standard input of another, creating powerful command chains.
|
||||
|
||||
**Basic Example:** Find `.txt` files in a directory listing.
|
||||
|
||||
```bash
|
||||
ls | grep ".txt"
|
||||
```
|
||||
This sends `ls`'s output to `grep` for filtering.
|
||||
|
||||
**Chaining Commands:** Analyze file ownership in a directory.
|
||||
|
||||
```bash
|
||||
ls -l /projects/bash_scripts | tail -n +2 | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | sort | uniq -c
|
||||
```
|
||||
This sequence lists files, removes the header, cleans spacing, extracts owner names, sorts them, and counts unique occurrences.
|
||||
|
||||
---
|
||||
|
||||
### Here-Documents (`<< DELIMITER`)
|
||||
|
||||
Here-documents (`<<`) provide multi-line input directly within your script or terminal, ideal for commands that read from STDIN without needing a separate temporary file.
|
||||
|
||||
Specify a custom delimiter (e.g., `EOF`):
|
||||
|
||||
```bash
|
||||
cat << END_MESSAGE
|
||||
This text will be passed as input to cat.
|
||||
It spans multiple lines.
|
||||
END_MESSAGE
|
||||
```
|
||||
Output:
|
||||
```
|
||||
This text will be passed as input to cat.
|
||||
It spans multiple lines.
|
||||
```
|
||||
You can also pipe the output of a here-document to another command:
|
||||
|
||||
```bash
|
||||
wc -l << MESSAGE_LINES
|
||||
Line one.
|
||||
Line two.
|
||||
Line three.
|
||||
MESSAGE_LINES
|
||||
```
|
||||
Output: `3` (counts the lines). Variables are expanded within here-documents.
|
||||
|
||||
---
|
||||
|
||||
### Here-Strings (`<<<`)
|
||||
|
||||
For piping a single string into a command's STDIN, use a here-string (`<<<`). This is cleaner than a here-document for single lines.
|
||||
|
||||
```bash
|
||||
wc -w <<<"This is a sample string for word count."
|
||||
```
|
||||
Output: `7` (counts words).
|
||||
Variables are also supported in here-strings.
|
||||
|
||||
---
|
||||
|
||||
### Summary of Redirection and Piping Operators
|
||||
|
||||
| **Operator** | **Description** |
|
||||
| :--- | :--- |
|
||||
| `>` | Redirect STDOUT to a file, overwriting existing content. |
|
||||
| `>>` | Redirect STDOUT to a file, appending to existing content. |
|
||||
| `<` | Redirect STDIN from a file. |
|
||||
| `2>` | Redirect STDERR to a file, overwriting existing content. |
|
||||
| `|` | Pipe STDOUT of one command to STDIN of another. |
|
||||
| `<<` | Here-document: Provide multi-line STDIN from the script. |
|
||||
| `<<<` | Here-string: Provide single-line STDIN from the command line. |
|
||||
Reference in New Issue
Block a user