Skip to content

Commit a20fb9f

Browse files
authored
Update README.md
1 parent 0362f69 commit a20fb9f

File tree

1 file changed

+93
-86
lines changed

1 file changed

+93
-86
lines changed

README.md

Lines changed: 93 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Bash Scripting Guide
22

3-
- Version: 1.0.0
4-
- Author:
5-
- Nathan Nellans
6-
- Email: me@nathannellans.com
7-
- Web:
8-
- https://www.nathannellans.com
9-
- https://github.com/nnellans/bash-guide
3+
- Version: 1.0.1
4+
- Author:
5+
- Nathan Nellans
6+
- Email: me@nathannellans.com
7+
- Web:
8+
- https://www.nathannellans.com
9+
- https://github.com/nnellans/bash-guide
1010

1111
> [!IMPORTANT]
1212
> This is an advanced guide and assumes you already know the basics of Bash. Think of this more like an advanced cheat sheet. I went through various sources, captured any notes that I felt were important, and organized them into the README file you see here.
@@ -19,31 +19,33 @@
1919
2020
---
2121

22-
# Table of Contents
23-
- [Script File Basics](#script-file-basics)
24-
- [Commands](#commands)
25-
- [Variables](#variables)
26-
- [Shell Variables](#shell-variables)
27-
- [Environment Variables](#environment-variables)
28-
- [Shell Functions](#shell-functions)
29-
- [Local Variables](#local-variables)
30-
- [Aliases](#aliases)
31-
- [Viewing Variables, Functions, and Aliases](#viewing-variables-functions-and-aliases)
32-
- [Standard Input, Output, and Error](#standard-input-output-and-error)
33-
- [Pattern Matching](#pattern-matching)
34-
- [Shell Arithmetic](#shell-arithmetic)
35-
- [Shell Expansions](#shell-expansions)
36-
- [If Statements](#if-statements)
37-
- [test and [ ] commands](#conditional-1-the-test-and----commands)
38-
- [\[\[ \]\] commands](#conditional-2-the----commands)
39-
- [(( )) commands](#conditional-3-the----commands)
40-
- [Case Statements](#case-statements)
41-
- [Loops](#loops)
42-
- [Array Variables](#array-variables)
43-
- [Positional Parameters](#positional-parameters)
22+
## Table of Contents
23+
24+
- [Script File Basics](#script-file-basics)
25+
- [Commands](#commands)
26+
- [Variables](#variables)
27+
- [Shell Variables](#shell-variables)
28+
- [Environment Variables](#environment-variables)
29+
- [Shell Functions](#shell-functions)
30+
- [Local Variables](#local-variables)
31+
- [Aliases](#aliases)
32+
- [Viewing Variables, Functions, and Aliases](#viewing-variables-functions-and-aliases)
33+
- [Standard Input, Output, and Error](#standard-input-output-and-error)
34+
- [Pattern Matching](#pattern-matching)
35+
- [Shell Arithmetic](#shell-arithmetic)
36+
- [Shell Expansions](#shell-expansions)
37+
- [If Statements](#if-statements)
38+
- [test and [ ] commands](#conditional-1-the-test-and----commands)
39+
- [\[\[ \]\] commands](#conditional-2-the----commands)
40+
- [(( )) commands](#conditional-3-the----commands)
41+
- [Case Statements](#case-statements)
42+
- [Loops](#loops)
43+
- [Array Variables](#array-variables)
44+
- [Positional Parameters](#positional-parameters)
4445

4546
---
46-
# Script File Basics
47+
48+
## Script File Basics
4749

4850
Shell scripts commonly use the `.sh` file extension.
4951

@@ -56,29 +58,31 @@ echo "something" # comments can also go after a command, with at least 1 space b
5658

5759
### Shebang
5860

59-
- This should be on line 1 of all Bash scripts. It tells the kernel which interpreter to use when running the script
60-
- Standard example: `#!/bin/bash`
61-
- Note: not all systems place `bash` in `/bin`
62-
- Portable version: `#!/usr/bin/env bash`
63-
- This version will run the first `bash` found in the `$PATH` variable
64-
- Note: not all systems place `env` in `/usr/bin`
61+
- This should be on line 1 of all Bash scripts. It tells the kernel which interpreter to use when running the script
62+
- Standard example: `#!/bin/bash`
63+
- Note: not all systems place `bash` in `/bin`
64+
- Portable version: `#!/usr/bin/env bash`
65+
- This version will run the first `bash` found in the `$PATH` variable
66+
- Note: not all systems place `env` in `/usr/bin`
6567

6668
### Shell options
6769

6870
The `set` command can be used to configure the shell. Some common options are:
69-
- `set -x` enables debug mode, where commands and arguments are printed out as they are executed
70-
- `set -e` exits the script immediately if any command fails (returns a non-zero exit status)
71-
- `set -u` exits the script immediately if you try to use a variable that's undefined
72-
- `set -o pipefail`
73-
- When piping commands together Bash will only return the exit status of the last command
74-
- This `set` command tells Bash to return a non-zero exit status if ANY of the commands in the pipeline fail
75-
- Bash lets you combine short parameters together, so you can use all options together: `set -xeuo pipefail`
71+
72+
- `set -x` enables debug mode, where commands and arguments are printed out as they are executed
73+
- `set -e` exits the script immediately if any command fails (returns a non-zero exit status)
74+
- `set -u` exits the script immediately if you try to use a variable that's undefined
75+
- `set -o pipefail`
76+
- When piping commands together Bash will only return the exit status of the last command
77+
- This `set` command tells Bash to return a non-zero exit status if ANY of the commands in the pipeline fail
78+
- Bash lets you combine short parameters together, so you can use all options together: `set -xeuo pipefail`
7679

7780
---
7881

79-
# Commands
82+
## Commands
8083

8184
There are multiple types of commands you can run with bash:
85+
8286
1. Executables (like binaries and scripts)
8387
2. Shell built-ins and keywords
8488
3. Shell functions
@@ -125,13 +129,14 @@ echo "$?" # the special variable $? expands to the exit status of the last comm
125129
126130
---
127131

128-
# Variables
132+
## Variables
129133

130134
### Shell Variables
131135

132136
Shell variables are only available to the particular shell session or script in which they are created.
133137

134138
Naming conventions:
139+
135140
- May contain letters, numbers, and underscores
136141
- Must not start with a number
137142
- Names are case-sensitive, so `varname` is different than `VarName`
@@ -172,10 +177,10 @@ echo "${var_name}plusSomeMoreText"
172177
```
173178

174179
> [GSG](https://google.github.io/styleguide/shellguide.html):
175-
> - Always double-quote strings containing variables
176-
> - Prefer `${var_name}` over `$var_name`, except:
177-
> - Don't use braces for special variables like `$@` or `$!`, unless strictly necessary
178-
> - Don't use braces for the first 10 positional parameters like `$0` and `$6`
180+
> - Always double-quote strings containing variables
181+
> - Prefer `${var_name}` over `$var_name`, except:
182+
> - Don't use braces for special variables like `$@` or `$!`, unless strictly necessary
183+
> - Don't use braces for the first 10 positional parameters like `$0` and `$6`
179184
180185
Assigning temporary values to variables:
181186

@@ -214,7 +219,7 @@ export VAR_NAME
214219
215220
Using Environment variables: same as Shell variables
216221

217-
# Shell Functions
222+
## Shell Functions
218223

219224
In your code, you must define your functions first before you can call them
220225

@@ -247,6 +252,7 @@ function name_of_function() {
247252
> - The `function` keyword enhances quick identification of functions
248253
249254
The `return` command is optional and is not required.
255+
250256
- By default, a Shell function will return the exit code from the last command it runs
251257
- If you want your function to return a specific exit code, use `return` followed by a number
252258

@@ -276,9 +282,9 @@ function_name "arg1" "arg2" "arg3"
276282
### Local Variables
277283

278284
You can define and use Local variables inside your functions.
279-
- Local variables are visible only to the function where they are defined, and its children
280-
- The names of Local variables will not conflict with other global variables defined elsewhere
281-
- This helps you to create portable functions
285+
- Local variables are visible only to the function where they are defined, and its children
286+
- The names of Local variables will not conflict with other global variables defined elsewhere
287+
- This helps you to create portable functions
282288

283289
Defining and using Local variables in a function:
284290

@@ -308,7 +314,7 @@ function_name() {
308314
> var_name="$(someCommand)"
309315
> ```
310316
311-
# Aliases
317+
## Aliases
312318
313319
> [GSG](https://google.github.io/styleguide/shellguide.html): Aliases should be avoided in scripts. For almost every purpose, shell functions are preferred over aliases.
314320
@@ -325,15 +331,15 @@ command2
325331
alias_name
326332
```
327333
328-
# Viewing Variables, Functions, and Aliases
334+
## Viewing Variables, Functions, and Aliases
329335

330336
There are multiple commands to view the Shell variables, Environment variables, Functions, and Aliases that are defined in your environment. Below, you'll see a graphic I created that shows some of those commands, and what information each one will return.
331337

332338
![](images/bash-environment.png)
333339

334340
---
335341

336-
# Standard Input, Output, and Error
342+
## Standard Input, Output, and Error
337343

338344
| Stream | Purpose | Default | File Descriptor |
339345
| --- | --- | --- | --- |
@@ -417,7 +423,7 @@ command &>> file.txt # append
417423

418424
---
419425

420-
# Pattern Matching
426+
## Pattern Matching
421427

422428
Used in a few ways: parameter expansion, filename expansion, the `[[ … ]]` compound commands, the `case` statement, etc.
423429

@@ -451,7 +457,7 @@ The following is not an exhaustive list:
451457
452458
---
453459
454-
# Shell Arithmetic
460+
## Shell Arithmetic
455461
456462
Used in a few ways: arithmetic expansion, the `(())` compound commands, the `let` & `expr` commands, `for` loops, etc.
457463
@@ -501,16 +507,16 @@ expression1 ? expression2 : expression3
501507
502508
---
503509
504-
# Shell Expansions
510+
## Shell Expansions
505511
506512
Bash performs 7 different types of shell expansions:
507513
508514
### 1. Brace Expansion
509515
510516
Brace Expansion lets you generate multiple strings from a given pattern. The pattern can be:
511-
- A comma-separated list of strings
512-
- A range of integers or characters, using 2 periods (`..`) to separate the starting and ending integers/characters
513-
- Optionally, you can include an integer at the end which specifies the increment that will be used
517+
- A comma-separated list of strings
518+
- A range of integers or characters, using 2 periods (`..`) to separate the starting and ending integers/characters
519+
- Optionally, you can include an integer at the end which specifies the increment that will be used
514520
515521
Brace Expansion is NOT performed on anything inside double quotes
516522
@@ -659,6 +665,7 @@ $(< file.txt) # you can use this
659665
### 5. Arithmetic Expansion
660666
661667
Expands to the result of an arithmetic expression
668+
662669
- Only supports integers
663670
- Supports the operators from the [Shell Arithmetic](#shell-arithmetic) section
664671
@@ -675,11 +682,11 @@ $(( (5 + 5) * 2 )) # grouping subexpressions with parenthesis
675682
676683
### 6. Word Splitting
677684
678-
- Word Splitting looks for spaces, tabs, and newline characters and treats them as delimiters between words
679-
- Spaces, tabs, and newlines are the default value for the special Shell variable `$IFS` (which stands for Internal Field Separator)
680-
- If you want Word Splitting to operate differently, then update the value of `$IFS`
681-
- Word Splitting only occurs on the results of other expansions, namely Parameter Expansion, Command Substitution, and Arithmetic Expansion
682-
- Word Splitting is NOT performed on anything inside double quotes
685+
- Word Splitting looks for spaces, tabs, and newline characters and treats them as delimiters between words
686+
- Spaces, tabs, and newlines are the default value for the special Shell variable `$IFS` (which stands for Internal Field Separator)
687+
- If you want Word Splitting to operate differently, then update the value of `$IFS`
688+
- Word Splitting only occurs on the results of other expansions, namely Parameter Expansion, Command Substitution, and Arithmetic Expansion
689+
- Word Splitting is NOT performed on anything inside double quotes
683690
684691
### 7. Filename Expansion
685692
@@ -706,7 +713,7 @@ ls /usr/bin/m*
706713
707714
---
708715
709-
# If Statements
716+
## If Statements
710717
711718
```shell
712719
if conditional; then
@@ -722,10 +729,10 @@ fi
722729
> - Put `; then` at the end of the same line that contains `if` or `elif`
723730
> - `fi` statements should be on their own line vertically aligned with the opening statement
724731
725-
- `conditional` can be any command, or set of commands, that will return an exit status
726-
- In Bash, if a command is successful it has an exit status of `0`, and if it fails it will have a non-zero exit status
727-
- `elif` and `else` are optional, only use them if you need to
728-
- There are multiple ways to write your conditional expression. Three of those ways will be explored below
732+
- `conditional` can be any command, or set of commands, that will return an exit status
733+
- In Bash, if a command is successful it has an exit status of `0`, and if it fails it will have a non-zero exit status
734+
- `elif` and `else` are optional, only use them if you need to
735+
- There are multiple ways to write your conditional expression. Three of those ways will be explored below
729736
730737
### Conditional 1: the `test` and `[ … ]` commands
731738
@@ -806,7 +813,7 @@ Newly added expressions:
806813
807814
---
808815
809-
# Case Statements
816+
## Case Statements
810817
811818
- When `case` finds a match it will run those commands and then exit, with no subsequent matches being attempted. This behavior can be modified by changing `;;` to a different option (but also see the `GSG:` note below)
812819
- As a fallback option, it is common to use `*` as the final pattern, as this will always match
@@ -841,7 +848,7 @@ esac
841848
842849
---
843850
844-
# Loops
851+
## Loops
845852
846853
> [GSG](https://google.github.io/styleguide/shellguide.html):
847854
> - Put `; do` at the end of the same line that contains `while`, `until`, or `for`
@@ -902,12 +909,12 @@ done
902909
903910
---
904911
905-
# Array Variables
912+
## Array Variables
906913
907-
- Bash arrays are one-dimensional (think of a single-column spreadsheet)
908-
- Arrays can be:
909-
- "indexed" which means they use a zero-based numeric index
910-
- "associative" which means they use a string-based index
914+
- Bash arrays are one-dimensional (think of a single-column spreadsheet)
915+
- Arrays can be:
916+
- "indexed" which means they use a zero-based numeric index
917+
- "associative" which means they use a string-based index
911918
912919
Naming standards: same as Shell variables
913920
@@ -1008,14 +1015,14 @@ echo "${sorted_array[@]}"
10081015
10091016
---
10101017
1011-
# Positional Parameters
1018+
## Positional Parameters
10121019
1013-
- Used in a few circumstances:
1014-
- Arguments passed to the shell when its invoked
1015-
- Arguments passed to a script
1016-
- Arguments passed to a shell function
1017-
- Can be reassigned using the `set` command
1018-
- Positional Parameter `0` always expands to the name of the shell or shell script, which means the first actual passed argument will be at Positional Parameter `1`
1020+
- Used in a few circumstances:
1021+
- Arguments passed to the shell when its invoked
1022+
- Arguments passed to a script
1023+
- Arguments passed to a shell function
1024+
- Can be reassigned using the `set` command
1025+
- Positional Parameter `0` always expands to the name of the shell or shell script, which means the first actual passed argument will be at Positional Parameter `1`
10191026
10201027
Using Positional Parameters:
10211028

0 commit comments

Comments
 (0)