update manuscript
This commit is contained in:
parent
393a288242
commit
d2c42689d8
|
@ -1,10 +1,10 @@
|
||||||
# Introduction
|
# FOREWORD
|
||||||
|
|
||||||
A collection of pure `bash` alternatives to external processes and programs. The `bash` scripting language is more powerful than people realise and you can accomplish most tasks without the need or dependency of external programs.
|
A collection of pure `bash` alternatives to external processes and programs. The `bash` scripting language is more powerful than people realise and most tasks can be accomplished without the need for or dependence on external programs.
|
||||||
|
|
||||||
Calling an external process in `bash` is expensive and excessive use will cause a noticeable slowdown. By sticking to built-in methods (*where possible*) your scripts and programs will be faster, require less dependencies and you'll gain a better understanding of the language itself.
|
Calling an external process in `bash` is expensive and excessive use will cause a noticeable slowdown. Scripts and programs written using built-in methods (*where applicable*) will be faster, require less dependencies and afford a better understanding of the language itself.
|
||||||
|
|
||||||
The contents of this book provide a reference for solving the problems encountered when writing programs and scripts in `bash`. The examples are in function format showcasing how to incorporate these solutions into your code.
|
The content of this book provides a reference for solving problems encountered when writing programs and scripts in `bash`. Examples are in function format showcasing how to incorporate these solutions into code.
|
||||||
|
|
||||||
<!-- CHAPTER END -->
|
<!-- CHAPTER END -->
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Strings
|
# STRINGS
|
||||||
|
|
||||||
## Trim leading and trailing white-space from string
|
## Trim leading and trailing white-space from string
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ if [[ "$var" == sub_string* ]]; then
|
||||||
printf '%s\n' "var starts with sub_string."
|
printf '%s\n' "var starts with sub_string."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Inverse (var doesn't start with sub_string).
|
# Inverse (var does not start with sub_string).
|
||||||
if [[ "$var" != sub_string* ]]; then
|
if [[ "$var" != sub_string* ]]; then
|
||||||
printf '%s\n' "var does not start with sub_string."
|
printf '%s\n' "var does not start with sub_string."
|
||||||
fi
|
fi
|
||||||
|
@ -366,7 +366,7 @@ if [[ "$var" == *sub_string ]]; then
|
||||||
printf '%s\n' "var ends with sub_string."
|
printf '%s\n' "var ends with sub_string."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Inverse (var doesn't start with sub_string).
|
# Inverse (var does not start with sub_string).
|
||||||
if [[ "$var" != *sub_string ]]; then
|
if [[ "$var" != *sub_string ]]; then
|
||||||
printf '%s\n' "var does not end with sub_string."
|
printf '%s\n' "var does not end with sub_string."
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Arithmetic
|
# ARITHMETIC
|
||||||
|
|
||||||
## Simpler syntax to set variables
|
## Simpler syntax to set variables
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
((var=var2*arr[2]))
|
((var=var2*arr[2]))
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ternary tests
|
## Ternary Tests
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Set the value of var to var2 if var2 is greater than var.
|
# Set the value of var to var2 if var2 is greater than var.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Traps
|
# TRAPS
|
||||||
|
|
||||||
Traps allow you to execute code on various signals. In `pxltrm` I'm using traps to redraw the user interface on window resize. Another use case is cleaning up temporary files on script exit.
|
Traps allow a script to execute code on various signals. In [pxltrm](https://github.com/dylanaraps/pxltrm) (*a pixel art editor written in bash*) traps are used to redraw the user interface on window resize. Another use case is cleaning up temporary files on script exit.
|
||||||
|
|
||||||
These `trap` lines should be added near the start of your script so any early errors are also caught.
|
Traps should be added near the start of scripts so any early errors are also caught.
|
||||||
|
|
||||||
**NOTE:** For a full list of signals, see `trap -l`.
|
**NOTE:** For a full list of signals, see `trap -l`.
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Performance
|
# PERFORMANCE
|
||||||
|
|
||||||
## Disable Unicode
|
## Disable Unicode
|
||||||
|
|
||||||
If your script doesn't require unicode, you can disable it for a speed boost. Results may vary but I've seen an improvement in Neofetch and some other smaller programs.
|
If unicode is not required, it can be disabled for a performance increase. Results may vary however there have been noticeable improvements in [neofetch](https://github.com/dylanaraps/neofetch) and other programs.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Disable unicode.
|
# Disable unicode.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Obsolete Syntax
|
# OBSOLETE SYNTAX
|
||||||
|
|
||||||
## Shebang
|
## Shebang
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ var="$(command "$(command)")"
|
||||||
|
|
||||||
## Function Declaration
|
## Function Declaration
|
||||||
|
|
||||||
Don't use the `function` keyword, it reduces compatibility with older versions of `bash`.
|
Do not use the `function` keyword, it reduces compatibility with older versions of `bash`.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Right.
|
# Right.
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
# Internal Variables
|
# INTERNAL VARIABLES
|
||||||
|
|
||||||
**NOTE**: This list does not include every internal variable (*You can
|
|
||||||
help by adding a missing entry!*).
|
|
||||||
|
|
||||||
For a complete list, see:
|
|
||||||
http://tldp.org/LDP/abs/html/internalvariables.html
|
|
||||||
|
|
||||||
## Get the location to the `bash` binary
|
## Get the location to the `bash` binary
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Information about the terminal
|
# INFORMATION ABOUT THE TERMINAL
|
||||||
|
|
||||||
## Get the terminal size in lines and columns (*from a script*)
|
## Get the terminal size in lines and columns (*from a script*)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Conversion
|
# CONVERSION
|
||||||
|
|
||||||
## Convert a hex color to RGB
|
## Convert a hex color to RGB
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ $ rgb_to_hex "255" "255" "255"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
# Code Golf
|
# CODE GOLF
|
||||||
|
|
||||||
## Shorter `for` loop syntax
|
## Shorter `for` loop syntax
|
||||||
|
|
||||||
|
@ -80,13 +80,13 @@ f(){ echo hi;}
|
||||||
f()(echo hi)
|
f()(echo hi)
|
||||||
|
|
||||||
# Using arithmetic
|
# Using arithmetic
|
||||||
# You can use this to assign integer values.
|
# This can be used to assign integer values.
|
||||||
# Example: f a=1
|
# Example: f a=1
|
||||||
# f a++
|
# f a++
|
||||||
f()(($1))
|
f()(($1))
|
||||||
|
|
||||||
# Using tests, loops etc.
|
# Using tests, loops etc.
|
||||||
# NOTE: You can also use ‘while’, ‘until’, ‘case’, ‘(())’, ‘[[]]’.
|
# NOTE: ‘while’, ‘until’, ‘case’, ‘(())’, ‘[[]]’ can also be used.
|
||||||
f()if true; then echo "$1"; fi
|
f()if true; then echo "$1"; fi
|
||||||
f()for i in "$@"; do echo "$i"; done
|
f()for i in "$@"; do echo "$i"; done
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
# Other
|
# OTHER
|
||||||
|
|
||||||
## Use `read` as an alternative to the `sleep` command
|
## Use `read` as an alternative to the `sleep` command
|
||||||
|
|
||||||
I was surprised to find out `sleep` is an external command and isn't a
|
Surprisingly, `sleep` is an external command and not a `bash` built-in.
|
||||||
built-in.
|
|
||||||
|
|
||||||
**CAVEAT:** Requires `bash` 4+
|
**CAVEAT:** Requires `bash` 4+
|
||||||
|
|
||||||
|
@ -28,8 +27,7 @@ read_sleep 30
|
||||||
## Check if a program is in the user's PATH
|
## Check if a program is in the user's PATH
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# There are 3 ways to do this and you can use either of
|
# There are 3 ways to do this and either one can be used.
|
||||||
# these in the same way.
|
|
||||||
type -p executable_name &>/dev/null
|
type -p executable_name &>/dev/null
|
||||||
hash executable_name &>/dev/null
|
hash executable_name &>/dev/null
|
||||||
command -v executable_name &>/dev/null
|
command -v executable_name &>/dev/null
|
||||||
|
@ -44,9 +42,9 @@ if ! type -p executable_name &>/dev/null; then
|
||||||
# Program is not in PATH.
|
# Program is not in PATH.
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Example (Exit early if program isn't installed).
|
# Example (Exit early if program is not installed).
|
||||||
if ! type -p convert &>/dev/null; then
|
if ! type -p convert &>/dev/null; then
|
||||||
printf '%s\n' "error: convert isn't installed, exiting..."
|
printf '%s\n' "error: convert is not installed, exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
@ -158,7 +156,7 @@ done
|
||||||
printf '\n'
|
printf '\n'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Get the list of functions from your script
|
## Get the list of functions in a script
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
get_functions() {
|
get_functions() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Arrays
|
# ARRAYS
|
||||||
|
|
||||||
## Reverse an array
|
## Reverse an array
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ $ array=(red green blue yellow brown)
|
||||||
$ random_array_element "${array[@]}"
|
$ random_array_element "${array[@]}"
|
||||||
yellow
|
yellow
|
||||||
|
|
||||||
# You can also just pass multiple arguments.
|
# Multiple arguments can also be passed.
|
||||||
$ random_array_element 1 2 3 4 5 6 7
|
$ random_array_element 1 2 3 4 5 6 7
|
||||||
3
|
3
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Loops
|
# LOOPS
|
||||||
|
|
||||||
## Loop over a range of numbers
|
## Loop over a range of numbers
|
||||||
|
|
||||||
Don't use `seq`.
|
Alternative to `seq`.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Loop from 0-100 (no variable support).
|
# Loop from 0-100 (no variable support).
|
||||||
|
@ -13,7 +13,7 @@ done
|
||||||
|
|
||||||
## Loop over a variable range of numbers
|
## Loop over a variable range of numbers
|
||||||
|
|
||||||
Don't use `seq`.
|
Alternative to `seq`.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Loop from 0-VAR.
|
# Loop from 0-VAR.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# File handling
|
# FILE HANDLING
|
||||||
|
|
||||||
**CAVEAT:** `bash` doesn't handle binary data properly in versions `< 4.4`.
|
**CAVEAT:** `bash` does not handle binary data properly in versions `< 4.4`.
|
||||||
|
|
||||||
## Read a file to a string
|
## Read a file to a string
|
||||||
|
|
||||||
|
@ -92,8 +92,7 @@ lines() {
|
||||||
|
|
||||||
**Example Function (bash 3):**
|
**Example Function (bash 3):**
|
||||||
|
|
||||||
This method uses less memory than the `mapfile` method and it's more
|
This method uses less memory than the `mapfile` method and works in `bash` 3 but it is slower for bigger files.
|
||||||
compatible but it's slower for bigger files.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
lines_loop() {
|
lines_loop() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# File Paths
|
# FILE PATHS
|
||||||
|
|
||||||
## Get the directory name of a file path
|
## Get the directory name of a file path
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Variables
|
# VARIABLES
|
||||||
|
|
||||||
## Assign and access a variable using a variable
|
## Assign and access a variable using a variable
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Escape Sequences
|
# ESCAPE SEQUENCES
|
||||||
|
|
||||||
Contrary to popular belief, there's no issue in using raw escape sequences. Using `tput` just abstracts the same ANSI escape sequences. What's worse is that `tput` isn't actually portable, there are a number of different `tput` variants on different Operating Systems each with different commands (*try and run `tput setaf 3` on a FreeBSD system*). The easiest solution ends up being raw ANSI sequences.
|
Contrary to popular belief, there is no issue in utilizing raw escape sequences. Using `tput` abstracts the same ANSI sequences as if printed manually. Worse still, `tput` is not actually portable. There are a number of `tput` variants each with different commands and syntaxes (*try `tput setaf 3` on a FreeBSD system*). Raw sequences are fine.
|
||||||
|
|
||||||
## Text Colors
|
## Text Colors
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Parameter Expansion
|
# PARAMETER EXPANSION
|
||||||
|
|
||||||
## Indirection
|
## Indirection
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
| `${VAR-STRING}` | If `VAR` is unset, use `STRING` as it's value.
|
| `${VAR-STRING}` | If `VAR` is unset, use `STRING` as it's value.
|
||||||
| `${VAR:=STRING}` | If `VAR` is empty or unset, set the value of `VAR` to `STRING`.
|
| `${VAR:=STRING}` | If `VAR` is empty or unset, set the value of `VAR` to `STRING`.
|
||||||
| `${VAR=STRING}` | If `VAR` is unset, set the value of `VAR` to `STRING`.
|
| `${VAR=STRING}` | If `VAR` is unset, set the value of `VAR` to `STRING`.
|
||||||
| `${VAR:+STRING}` | If `VAR` isn't empty, use `STRING` as it's value.
|
| `${VAR:+STRING}` | If `VAR` is not empty, use `STRING` as it's value.
|
||||||
| `${VAR+STRING}` | If `VAR` is set, use `STRING` as it's value.
|
| `${VAR+STRING}` | If `VAR` is set, use `STRING` as it's value.
|
||||||
| `${VAR:?STRING}` | Display an error if empty or unset.
|
| `${VAR:?STRING}` | Display an error if empty or unset.
|
||||||
| `${VAR?STRING}` | Display an error if unset.
|
| `${VAR?STRING}` | Display an error if unset.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Brace Expansion
|
# BRACE EXPANSION
|
||||||
|
|
||||||
## Ranges
|
## Ranges
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue