category: CLI
layout: 2017/sheet
tags: [Featured]
-updated: 2019-10-02
+updated: 2020-07-04
keywords:
- Variables
- Functions
echo {A,B}.js
```
-| `{A,B}` | Same as `A B` |
+| Expression | Description |
+| ---------- | ------------------- |
+| `{A,B}` | Same as `A B` |
| `{A,B}.js` | Same as `A.js B.js` |
-| `{1..5}` | Same as `1 2 3 4 5` |
+| `{1..5}` | Same as `1 2 3 4 5` |
See: [Brace expansion](http://wiki.bash-hackers.org/syntax/expansion/brace)
STR="/path/to/foo.cpp"
echo ${STR%.cpp} # /path/to/foo
echo ${STR%.cpp}.o # /path/to/foo.o
+echo ${STR%/*} # /path/to
echo ${STR##*.} # cpp (extension)
echo ${STR##*/} # foo.cpp (basepath)
### Substitution
-| Code | Description |
-| --- | --- |
-| `${FOO%suffix}` | Remove suffix |
-| `${FOO#prefix}` | Remove prefix |
-| --- | --- |
-| `${FOO%%suffix}` | Remove long suffix |
-| `${FOO##prefix}` | Remove long prefix |
-| --- | --- |
-| `${FOO/from/to}` | Replace first match |
-| `${FOO//from/to}` | Replace all |
-| --- | --- |
-| `${FOO/%from/to}` | Replace suffix |
-| `${FOO/#from/to}` | Replace prefix |
+| Code | Description |
+| ----------------- | ------------------- |
+| `${FOO%suffix}` | Remove suffix |
+| `${FOO#prefix}` | Remove prefix |
+| --- | --- |
+| `${FOO%%suffix}` | Remove long suffix |
+| `${FOO##prefix}` | Remove long prefix |
+| --- | --- |
+| `${FOO/from/to}` | Replace first match |
+| `${FOO//from/to}` | Replace all |
+| --- | --- |
+| `${FOO/%from/to}` | Replace suffix |
+| `${FOO/#from/to}` | Replace prefix |
### Comments
### Substrings
-| `${FOO:0:3}` | Substring _(position, length)_ |
-| `${FOO:-3:3}` | Substring from the right |
+| Expression | Description |
+| --------------- | ------------------------------ |
+| `${FOO:0:3}` | Substring _(position, length)_ |
+| `${FOO:(-3):3}` | Substring from the right |
### Length
-| `${#FOO}` | Length of `$FOO` |
+| Expression | Description |
+| ---------- | ---------------- |
+| `${#FOO}` | Length of `$FOO` |
### Manipulation
echo ${STR^^} #=> "HELLO WORLD!" (all uppercase)
```
-
### Default values
-| `${FOO:-val}` | `$FOO`, or `val` if not set |
-| `${FOO:=val}` | Set `$FOO` to `val` if not set |
-| `${FOO:+val}` | `val` if `$FOO` is set |
-| `${FOO:?message}` | Show error message and exit if `$FOO` is not set |
+| Expression | Description |
+| ----------------- | -------------------------------------------------------- |
+| `${FOO:-val}` | `$FOO`, or `val` if unset (or null) |
+| `${FOO:=val}` | Set `$FOO` to `val` if unset (or null) |
+| `${FOO:+val}` | `val` if `$FOO` is set (and not null) |
+| `${FOO:?message}` | Show error message and exit if `$FOO` is unset (or null) |
-The `:` is optional (eg, `${FOO=word}` works)
+Omitting the `:` removes the (non)nullity checks, e.g. `${FOO-val}` expands to `val` if unset otherwise `$FOO`.
Loops
-----
### Reading lines
```bash
-< file.txt | while read line; do
+cat file.txt | while read line; do
echo $line
done
```
### Arguments
-| Expression | Description |
-| --- | --- |
-| `$#` | Number of arguments |
-| `$*` | All arguments |
-| `$@` | All arguments, starting from first |
-| `$1` | First argument |
+| Expression | Description |
+| --- | --- |
+| `$#` | Number of arguments |
+| `$*` | All arguments |
+| `$@` | All arguments, starting from first |
+| `$1` | First argument |
+| `$_` | Last argument of the previous command |
See [Special parameters](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables).
| --- | --- |
| `(( NUM < NUM ))` | Numeric conditions |
-| Condition | Description |
-| --- | --- |
-| `[[ -o noclobber ]]` | If OPTIONNAME is enabled |
-| --- | --- |
-| `[[ ! EXPR ]]` | Not |
-| `[[ X ]] && [[ Y ]]` | And |
-| `[[ X ]] || [[ Y ]]` | Or |
+#### More conditions
+
+| Condition | Description |
+| -------------------- | ------------------------ |
+| `[[ -o noclobber ]]` | If OPTIONNAME is enabled |
+| --- | --- |
+| `[[ ! EXPR ]]` | Not |
+| `[[ X && Y ]]` | And |
+| `[[ X || Y ]]` | Or |
### File conditions
echo "String is empty"
elif [[ -n "$string" ]]; then
echo "String is not empty"
+else
+ echo "This never happens"
fi
```
```bash
# Combinations
-if [[ X ]] && [[ Y ]]; then
+if [[ X && Y ]]; then
...
fi
```
```bash
# Regex
-if [[ "A" =~ "." ]]
+if [[ "A" =~ . ]]
```
```bash
```bash
echo ${Fruits[0]} # Element #0
+echo ${Fruits[-1]} # Last element
echo ${Fruits[@]} # All elements, space-separated
echo ${#Fruits[@]} # Number of elements
echo ${#Fruits} # String length of the 1st element
echo ${#Fruits[3]} # String length of the Nth element
echo ${Fruits[@]:3:2} # Range (from position 3, length 2)
+echo ${!Fruits[@]} # Keys of all elements, space-separated
```
### Operations
### Glob options
```bash
-set -o nullglob # Non-matching globs are removed ('*.foo' => '')
-set -o failglob # Non-matching globs throw errors
-set -o nocaseglob # Case insensitive globs
-set -o globdots # Wildcards match dotfiles ("*.sh" => ".foo.sh")
-set -o globstar # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb')
+shopt -s nullglob # Non-matching globs are removed ('*.foo' => '')
+shopt -s failglob # Non-matching globs throw errors
+shopt -s nocaseglob # Case insensitive globs
+shopt -s dotglob # Wildcards match dotfiles ("*.sh" => ".foo.sh")
+shopt -s globstar # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb')
```
Set `GLOBIGNORE` as a colon-separated list of patterns to be removed from glob
### Commands
-| `history` | Show history |
+| Command | Description |
+| --------------------- | ----------------------------------------- |
+| `history` | Show history |
| `shopt -s histverify` | Don't execute expanded result immediately |
### Expansions
-| `!$` | Expand last parameter of most recent command |
-| `!*` | Expand all parameters of most recent command |
-| `!-n` | Expand `n`th most recent command |
-| `!n` | Expand `n`th command in history |
+| Expression | Description |
+| ------------ | ---------------------------------------------------- |
+| `!$` | Expand last parameter of most recent command |
+| `!*` | Expand all parameters of most recent command |
+| `!-n` | Expand `n`th most recent command |
+| `!n` | Expand `n`th command in history |
| `!<command>` | Expand most recent invocation of command `<command>` |
### Operations
-| `!!` | Execute last command again |
-| `!!:s/<FROM>/<TO>/` | Replace first occurrence of `<FROM>` to `<TO>` in most recent command |
-| `!!:gs/<FROM>/<TO>/` | Replace all occurrences of `<FROM>` to `<TO>` in most recent command |
-| `!$:t` | Expand only basename from last parameter of most recent command |
-| `!$:h` | Expand only directory from last parameter of most recent command |
+| Code | Description |
+| -------------------- | --------------------------------------------------------------------- |
+| `!!` | Execute last command again |
+| `!!:s/<FROM>/<TO>/` | Replace first occurrence of `<FROM>` to `<TO>` in most recent command |
+| `!!:gs/<FROM>/<TO>/` | Replace all occurrences of `<FROM>` to `<TO>` in most recent command |
+| `!$:t` | Expand only basename from last parameter of most recent command |
+| `!$:h` | Expand only directory from last parameter of most recent command |
`!!` and `!$` can be replaced with any valid expansion.
### Slices
-| `!!:n` | Expand only `n`th token from most recent command (command is `0`; first argument is `1`) |
-| `!^` | Expand first argument from most recent command |
-| `!$` | Expand last token from most recent command |
-| `!!:n-m` | Expand range of tokens from most recent command |
-| `!!:n-$` | Expand `n`th token to last from most recent command |
+| Code | Description |
+| -------- | ---------------------------------------------------------------------------------------- |
+| `!!:n` | Expand only `n`th token from most recent command (command is `0`; first argument is `1`) |
+| `!^` | Expand first argument from most recent command |
+| `!$` | Expand last token from most recent command |
+| `!!:n-m` | Expand range of tokens from most recent command |
+| `!!:n-$` | Expand `n`th token to last from most recent command |
`!!` can be replaced with any valid expansion i.e. `!cat`, `!-2`, `!42`, etc.
### Special variables
-| `$?` | Exit status of last task |
-| `$!` | PID of last background task |
-| `$$` | PID of shell |
-| `$0` | Filename of the shell script |
+| Expression | Description |
+| ---------- | ---------------------------- |
+| `$?` | Exit status of last task |
+| `$!` | PID of last background task |
+| `$$` | PID of shell |
+| `$0` | Filename of the shell script |
See [Special parameters](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables).