Bourne Again Shell
- Kernel is the Core of the OS, OSX uses the Mach Kernel
- Shell is the outer layer of the OS, the interface to communicate with the Kernel, OSX uses the bash shell. You can switch between shells, it's just the interface - not like the OS
-
Echo -
echo <statement>print to stdoutecho hello $nameis ok, but special chars must be escapedecho 'hello $name'will print literally, not interpreting the variableecho "hello $name"will interpret the var and escape charactersecho(without args) prints an empty lineecho -e \<escaped_sequence>m- for colors and styles- e.g. color
echo -e '\033[34;42mColored Text\033[0m'-34means blue font,42means green for background - e.g. underline
echo -e '\033[4;31mError\033[0m'-4is underline,0at the end resets styles - you can use
tputfor a more verbose way of defining styles, e.g.echo -e $(tput setaf 1)"red string"tput sgr0resets styles
- e.g. color
-
Viewing files
more <file>- browse file page by pagehead <file>- print first linestail <file>- print last lines
-
Expansions
- brace expansion:
touch file_{0..1000}creates 1001 files,echo {1..10..2}- prints ints from 1 to 10, counting by 2s (1,3,5,7,9)
- brace expansion:
-
Piping - pipe takes the result of one command and pipes it into another one, e.g.
ls | moredisplays list of files with pagination -
Redirection -
>, works withstdin,stdout, andstderr.stdoutandstderrcan be represented by1and2,- i.e.:
cp -v * ../somefolder 1>../success.txt 2> ../error.txtcopies everything from current dir (with verbosity), but printsstdoutandstderrto files, not to terminal - it's redirecting 1and2can be together represented by&- redirecting to
/dev/nulltrashes the output
- i.e.:
-
grep- use asgrep <pattern> <file>, option-imakes it case-insensitive
- start with hashbang aka shebang -
#!/bin/bash- which specifies the path to bash executable - commented lines start with
# chmod +x <filename>to make the script executable- assign the result of a command to a variable -
where=$(pwd)
name=Walpurgia,town="Little Bindle",len=134declare a variabledeclare -i d=32marks that variable as an integerdeclare -r d=32marks that variable as read-onlydeclare -l d=LsadfW # => lsadfwlowercasesdeclare -u d=Lssdfw # => LSSDFWuppercases$namecalls a variable
$HOME,$PWD,$PATH,$HOSTNAME,$BASH_VERSION$MACHTYPEreturns the machine type$SECONDSreturns no. of seconds the bash session has been running (in script, from when the script started)$0returns the name of the script
- bash only works with integers, but you can use
bcprogram to get floats -echo 1/3 | bc -l - arithmetic operations must be enclosed as
((expression)) - assign to a variable -
four=$((3+1)) - Operators:
/,*,+,-,%**is exponentiation++,--,+=,-=,*=,/=
[[ expression ]]return1or0,0means success,1is failure[[ $a < $b ]], and others:>,>=,<=,==,!=- logic -
[[ $a && $b ]]and||, and[[ ! $b ]] [[ -z $a ]]- is it null?[[ -n $a ]]- is it not null?[[ $string =~ [<regexp>] ]]- regex
- concatenation:
$c=$a$b - character count:
${#c} - substring:
d=${c:3}-discfrom 3rd char to ende=${c:3:10}- chars 3 to 10
- replace:
${<stringname>/<searchterm>/<replacewith>}, e.g.${name/Bogdan/Peter}- to replace all instances double the first
/ - replace only if search term is at the beginning - add
#before search term - replace only if at the end -
%before search term - wildcards -
${name/B*/Nikolai}
- to replace all instances double the first
- date formatting -
date +"<format string>", e.g.date +"%d, %m, %Y" printf -v dassigns the output to variabledprintf- lets you print out data with a particular format - e.g.printf "Name:\t%s\nID:\t%04d\n" "Adam" "43"will print
Name: Adam
ID: 0043
fruits=("banana" "apple" "pear"),- retrieve:
echo ${fruits[0]}(whole array -echo ${fruits[@]}, last elem. -echo ${fruits[@]: -1}) - set:
fruits[1]="orange" - push:
fruits+="kiwi" - get length:
echo ${#fruits[@]}
- retrieve:
- Associative arrays (key-value pairs) - bash version >=4
declare -A myarray
myarray[color]=blue
myarray["Home Address"]="12 James Street"
echo ${myarray[color]}- write to file
echo "Some text" > file.txt - read a file
cat < file.txt - zero out a file
> file.txt - append to file
echo "Some more text" >> file.txt
- 'if' statement
if <expression>
then
echo "True"
elif <expression 2>; then
echo "First was false, this is true"
fi- 'while' loop, can be reversed, as with 'until' instead of while
while <expression>; do
# ...
done- 'for in' and 'for' loops
for <variable> in <collection>
do
# ...
donefor (( i=0; i<=10; i++ ))
do
# ...
done# with an associative aray:
for key in "${!myarray[@]}"
do
echo "$key has value ${myarray[$key]}"
done- case
a="dog"
case $a in
cat) echo "Feline";;
dog|puppy) echo "Canine";;
*) echo "No match";;
esacfunction greet {
echo "Hello, $1"
}
greet Pedro # Hello, Pedro$@is an array with all arguments
$1,$2, etc. are arguments passed to the script$#contains the number of arguments
# here colons after flags mean we expect the values fo be there, they are not optional
# colon at the beginning of flags list means they can be additional flags, then represented by '?)' in case
while getopts u:p: option
do
case $option in
u) user=$OPTARG;;
p) pass=$OPTARG;;
esac
done
echo "User: $user, password: $pass"echo "What is your name?"
read name
echo "$name, that's a nice name"read -s password,-sis 'silent' flag- in one line:
read -p "Why me?" reason
select animal in "cat" "dog" "bird"
do
echo "You've selected $animal"
break
doneif [ $# -lt 3 ]; then
echo "This command requires three arguments"
else
echo "All right, carry on"
firead -p "Favourite writer? [Vonnegut] " a
# here we test for not null, but we can test regex or sth else as well
while [[ -z "$a" ]]; do
a="Vonnegut"
done
echo "$a was selected"