Bash Basics
Bash is a commonly used language on most Linux System. The name Bash stands for ‘Bourne Again SHell’. It is developed as a replacement/improvement for Bourne Shell(sh).
Installation
To install or update bash in MacOS using Homebrew
1 | brew install bash |
Hello World
1 |
|
Script Execution
Bash script file is a text file with commands. To execute the bash script, first make the file executable
1 | chmod +x myscript |
Then you can run the script by prefixing it with ./
. This tells Bash to look for the script in current directory. by default Bash only executes commands in $PATH
.
1 | ./myscript |
An alternative way is to use bash
command. But the problem for this approach is that you can’t provide arguments to the script.
1 | bash myscript |
You can also add the script to system path so that it can be executed in any path. A common place to store the script is /usr/local/bin.
Shebang
#!/bin/bash
is not a comment, it is a Shebang. Shebang should be the first line in a bash file. Shebang tells Bash how to do the interpretation. /bin/bash is the path to the interpreter that is used.
Print Output to Terminal
echo
command is the most used command to print output to the terminal
1 | echo 'hello world' |
output
1 | hello world |
Variable
Like other script languages, you can define variable in Bash. You use assign operator =
to assign value to a variable. Note that you can’t have space before and after =
sign.
1 | var0=Hello |
This is Invalid because var0 follows a space. Bash will inteprete var0 as a command
1 | $ var0 = 2 |
To reference a variable, you prefix a variable with a dollar sign. ‘$’ character here is used for parameter expansion.
1 | echo $var2 |
In a string defined by a double quote, the variables are also referenced. This doesn’t work for string defined by single quote.
1 | echo "$var0 $var1!" |
will print
1 | Hello World! |
Parameter Expansion
The ‘$’ character introduces parameter expansion.
The basic form of parameter expansion is ${parameter}. The braces are optional. It is used so that the characters following the variable will not be misinterpreted as part of a parameter.
Ther are many forms of parameter expansion. You can use it to get parameter length, get substring or do substitution.
Getting User Input
use read
command to read input from user. if input contains backslash, add -r option. see Bash Guide for Beginners - Catching user input
1 | read -p "username: " username |
Command Substitution
Command Substitution allows user to execute a command and replace the text of the command with the output of the command.
Syntax - recommended is $(). Backquote is not recommended.
1 | $(command) |
or
1 | `command` |
example - create file with date postfix
1 | touch file-$(date +%y-%m-%d).txt |
exmaple - generate uuid
1 | uuid=$(uuidgen) |
Pass Arguments to Bash Script
You can pass parameter to bash script. use $1
, $2
to access them. $0 is the name of the Bash script
Here is a file hello.sh
1 |
|
If you run ./hello.sh Alice Bob Cathy
. The output will be
1 | ./hello.sh Alice Bob Cathy |
You can assign the arguments to an array. Note that the first element of the array is the first argument not the name of the Bash script.
1 | args=("$@") |
You can get the number of arguments using $#
1 | echo $# |
Exit Code
exit 0
is for normal exit of the application. scripts should return non-zero value if it fails. You can use echo $?
to check the exit status.
1 | echo $? |
Ignore the error
Sometimes you want to ignore an error and continue the execution. To do that, just add || antohercommand
to the end.
1 | command || true |
Math Calculation
1 | var1=$(( 1 + 2 )) |
Conditional Statements
If Statement
1 | if command; then |
Here semicolon is needed. it is used to separate commands. You will get a syntax error if you don’t have it.
In the if statement, square brackets([]) is often used to test condition. square bracket use command test
to evaluate the expression. see test online man page for test
command usage.
test command parameter | description |
---|---|
! expr | the expr is false |
-n STRING | the length of STRING is nonzero |
STRING | equivalent to -n STRING |
-z STRING | the length of STRING is zero |
STRING1 = STRING2 | the strings are equal |
STRING1 != STRING2 | the strings are not equal |
INTEGER1 -eq INTEGER2 | INTEGER1 is equal to INTEGER2 |
INTEGER1 -gt INTEGER2 | INTEGER1 is greater than INTEGER2 |
INTEGER1 -lt INTEGER2 | INTEGER1 is less than INTEGER2 |
file test command | description |
---|---|
-e FILE | FILE exists |
-f FILE | FILE exists and is a regular file |
-d FILE | FILE exists and is a directory |
Sometimes double square([[) bracket is used to test condition. unlike [, which is a POSIX shell command, [[ is a bash keyword. [[ is supported by bash and other shells(zsh, ksh). Parsing rules for keywords makes conditions written by [[ easier to understand.
if… satement example
If parameter is not provided, print the usage message
1 | if [ -z $1 ]; then |
if variable a is greate than b, then print ‘a > b’
1 | if [ $a -gt $b ]; then |
Check if file exists and is a regular file.
1 | if [ -f $1 ] |
if…else… statement example
1 | if ! [ -z $1 ] |
print parameter. If parameter is not provided, print the usage message.
if…elif…else statement
1 | if [ -d $1 ]; then |
Case Statement
1 | case <variable> in |
case statement example
1 | system=$(uname) |
It will print a massage base on the system the user is in.
Loops
While
While Syntax, you can use break and continue in the while body.
1 | while [ <some test> ] |
while example - print 0 - 4
1 | count=0 |
while example - read lines from file
1 | while read line; do |
break example
1 | while read line; do |
continue example
1 | input="/etc/hosts" |
For
1 | for var in <list> |
Example - process regular text files in the current folder
1 | curFiles="./*" |
Function
Unlike functions in other programming language, bash function do not return anything to the caller. To return value, you use global variable to store the value.
To define and call a function
1 | function printSeparater { |
Or you can define it like this
1 | printSeparater() { |
parameters can be access using $1
, $2
1 | printtitle() { |