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 $name
is 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'
-34
means blue font,42
means green for background - e.g. underline
echo -e '\033[4;31mError\033[0m'
-4
is underline,0
at the end resets styles - you can use
tput
for a more verbose way of defining styles, e.g.echo -e $(tput setaf 1)"red string"
tput sgr0
resets 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 | more
displays list of files with pagination -
Redirection -
>
, works withstdin
,stdout
, andstderr
.stdout
andstderr
can be represented by1
and2
,- i.e.:
cp -v * ../somefolder 1>../success.txt 2> ../error.txt
copies everything from current dir (with verbosity), but printsstdout
andstderr
to files, not to terminal - it's redirecting 1
and2
can be together represented by&
- redirecting to
/dev/null
trashes the output
- i.e.:
-
grep
- use asgrep <pattern> <file>
, option-i
makes 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=134
declare a variabledeclare -i d=32
marks that variable as an integerdeclare -r d=32
marks that variable as read-onlydeclare -l d=LsadfW # => lsadfw
lowercasesdeclare -u d=Lssdfw # => LSSDFW
uppercases$name
calls a variable
$HOME
,$PWD
,$PATH
,$HOSTNAME
,$BASH_VERSION
$MACHTYPE
returns the machine type$SECONDS
returns no. of seconds the bash session has been running (in script, from when the script started)$0
returns the name of the script
- bash only works with integers, but you can use
bc
program 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 ]]
return1
or0
,0
means success,1
is 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}
-d
isc
from 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 d
assigns the output to variabled
printf
- 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
# ...
done
for (( 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";;
esac
function 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
,-s
is 'silent' flag- in one line:
read -p "Why me?" reason
select animal in "cat" "dog" "bird"
do
echo "You've selected $animal"
break
done
if [ $# -lt 3 ]; then
echo "This command requires three arguments"
else
echo "All right, carry on"
fi
read -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"