Table of Contents
- streams
- variables
- arrays
- arithmetic
- expansion
- built in and environment variables
- pipelines
- redirection
- lists
- process substitution
- compound commands
- functions
- some commands/utils
Bash is a shell with a scripting language that allows you to do things like concatenating commands. to make a script write your bash commands in a file. the first line of the file must contain a shebang: #!/usr/bin/env bash
which tells the shell how to run the file.
This article uses primarily the gnu bash manual and the x in y minutes guide as sources and is meant to be an approximate overview.
streams
bash has three standard streams: stdin, stdout, and stderr. stdin is naturally where what the user types to console goes. stderr and stdout often both write to console. stdout is represented as the number 1 in certain cases and stderr as 2.
variables
variable assignment looks like name="value"
but crucially cannot have spaces or bash will interpret the name as a command.
to dereference a variable and use its value write it as "$name"
it must use double quotes and not single quotes, omitting the quotes is technically possible but not recommended.
arrays
you create an array much like a variable
array=(first second third)
and index into it like you expect array[0]
but you can also return the whole array array[@]
and index into a range of that array array[@]:0:2
. You can also get the length of an array with #array[@]
arithmetic
check out the gnu manual for a full breakdown. I will just say its mostly what you expect. I will note that:
**
is power>> <<
are bitwise shifts| &
are bitwise OR and AND while|| &&
are logical^
is XOR- there is a ternary operator:
condition?expr:expr
~=
lets you check a string against a regex
expansion
Is the process by which a pattern is expanded out into all the words it describes. (for example a regular expression expanded into the language it describes). See the gnu manual on expansion.
command substitution
$(<commands>)
Command substitution allows a command to be treated as its output. In other words you can execute a command in place and use its data as if it were a dereferenced variable.
parameter expansion
parameter expansion lets you modify a command's argument on the fly, as well as indirection, for instance:
var="hello world"
indirect="var"
echo "${var/hello/hey}" #=> hey world
echo "${!indirect}" #=> hello world
echo "${var:0:4}" #=> hello
echo "${var:-"default"}
# default value if var is missing or empty
brace expansion
Brace expansion is used to generate ranges of characters and numbers.
{1..5} #=> 1 2 3 4 5
{a..e} #=> a b c d e
you cannot use variables inside the brace expansion.
built in and environment variables
$?
is the last program's return variable$$
is the script's PID$#
number of arguments$@
all arguments passed to the script$1, $2 ...
are the numbered arguments$PWD
is the working directory as a variable$USER
current user's name$PATH
is a list of paths the shell will search for command executables-
is the previous working directory..
is the parent directory.
is the current directory~
is the home directory
pipelines
The |
character is called a pipe and directs the output of its left hand command into the input of the right hand command. |&
is another type of pipe that also connects the left hand error to the right hand input. A series of commands connected by pipes is called a pipeline.
redirection
Redirects are similar to pipes but instead of hooking output into input, it hooks a file or stream into a command's input or output. > file
allows an output to be written to a file, and < file
allows a file to be used as input.
>>
and <<
do the same but append rather than overwrite.
see more details at the gnu manual
lists
Lists are series of commands or pipelines connected together by list operators.
||
is the OR operator. It will execute its LHS and then execute its RHS if the LHS has a non-zero exit status (the command failed).
&&
is the AND operator. It will execute its LHS and then execute its RHS if the LHS exited with a zero exit status (the command succeeded).
;
is the sequence operator. It will run the LHS then the RHS regardless of exit status, it can be replaced with a newline.
&
is like ;
by executes the LHS in an asynchronous shell
process substitution
Process substitution allows you to treat the input or output of a process as a file name while running the process asynchronously. >(list)
allows you to write to the input as a file. <(list)
allows you to read the output of list as a file. there cannot be a space between the angle bracket and the left paren.
compound commands
These are code blocks that can hold multiple commands. Each compound command is begun and terminated by a reserved word or character.
looping commands
Bash has three loops: until, while, for.
until
until <condition command>;do
<commands>;
done
The until loop goes until the condition command has zero exit status. The block inherits the status of its last executed command or zero if no commands were executed.
while
while <condition command>; do
<commands>;
done
The While loop goes until the condition command has a non-zero exit status. The exit status of the block is the status of the last run command of the do block or zero if no commands were run.
for
for loops have two forms:
#iterator
for ((i=1; i<n; i++)); do
<commands>;
done
#named variable
for <name> in <array>; do
<commands>;
done
note that the array here can also be an expansion
conditional commands
arithmetic commands
((arithmetic expression))
evaluates the math and gives an exit status of zero if the arithmetic expression evaluates to a non-zero value and zero otherwise.
[[conditional expression]]
evaluates a conditional expression and returns a 0 or 1 based on the result(0 is true and 1 is false).
if
if <condition command>; then
<commands>
elif <condition>; then
<commands>
else
<commands>
fi
Note that elif
and else
are optional.
case
case <var> in
pattern1) <command>;;
pattern2) <command>;&
pattern3) <command>;;&
*) <default command>;;
esac
patterns can be regular expressions, or numbers.
select
Select is useful for creating menus. It prints all the options with in the given list with numbers to std err and waits for a number over std in. it then runs that commands and loops until a break command is selected
select <name> in <list>; do
<commands>;
break;
done
see the gnu manual on conditional commands for more.
groups
(list)
causes all the listed commands to be executed in a subshell.
{list;}
executes the listed commands without a subshell. the trailing semicolon is required.
functions
define a function with
name () {
return exit_status #return is not required
}
#or
function name (){ #note that in this case () is optional
return exit_status
}
we don't actually put arguments in the parentheses since we refer to them with $1 $2
etc
to call a function we simply write its name and any arguments
func arg1 arg2
functions are scoped and have access to their parent scopes. However, local variables must be declared with the local
keyword like so
var1="foo"
var2="baz"
func1() {
local var1="bar"
echo $var1 #=> bar
func2 #=> bar
}
func2() {
echo $var1
}
func2 #=> foo
func3() { var2="bat"; }
func4() {
func3;
echo $var2; #=>bat
}
some commands/utils
cd path
changes your working directoryls
lists the directories in the working directorytouch name
creates a new file with namemkdir name
creates a new directory with namemv path1 path2
moves the file at path1 to path2cp
same as move but doesn't delete the originalpwd
prints working directoryecho
prints its argumentgrep
allows you to search using pattern matchingsed
allows you to match with pattern matchinguniq
allows you to omit repeated lineshead
andtail
allows you to cat the first or last n lines of a filecut
prints a column of text from a file limited by a given delimiter.jobs
shows all running async jobscat path
prints file to consoleread var
lets you read user input and store it in a variablealias
lets you name a specific command e.galias hi=echo "hey"
trap
allows you to execute a command on a given signal
you can end processes with ctrl+c
and pause them with ctrl+z
. ctrl+d
sends an EOF token.