Người biên soạn: Nguyễn Đức Tây
fb.com/taaytungstieenf
PART A. From Command-Line to Bash Script
BASH SCRIPTING ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
$ nano hello.sh
1. Create & run .sh file ~ echo “Hello World”
$ bash hello.sh
USING SHEBANG ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
$ nano script.sh
~ #!/bin/bash
1. On Bash Scripting code ~ echo “Hello World”
$ chmod +x script.sh
$ ./script.sh
$ nano script.sh
~ #!/bin/python3
2. On Python code ~ python(“Hello World”)
$ chmod +x script.sh
$ ./scirpt.sh
USING ARGUMENTS ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
$ nano test.sh
~ #!/bin bash
~ echo $1 #1st variable
1. Create sh file ~ echo $2 #2nd varibale
~ echo $@ #all variable
~ echo “There are” $# “arguments!”
$ chmod +x test.sh
2. Pass arguments into sh file $ ./test.sh one two three four five
PART B. Data Type in Bash Scripting
STRING ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
$ a=1; b=2
$ echo $((a+b))
1. Assign & calculate as integers
$ a=1; b=2.5
2. Assign & calculate as decimals $ echo “$a+$b” | bc
$ a=10; b=3
3. Calculate as decimals with scale $ echo “scale=2; $a/$b” | bc
INTEGER ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
$ declare -i a=1 b=2
1. Declare & use variable $ a+=1 b+=2
ARRAY ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
1. Create numerical-indexed array $ declare -a array=(1 2 3 4 5)
2. Print full array $ echo ${array[@]}
3. Print the number of element in array $ echo ${array[#]}
4. Print the first element in array $ echo ${array[0]}
5. Print the elements from first to third $ echo ${array[@]:0:2}
6. Concatenate element and show array $ array+=(6); echo ${array[@]}
ASSOCIATIVE ARRAY ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
7. Create associative array in 1 line $ declare -A person=([name]=”Tae Ng“ [age]=26 [nationality]=VN)
$ declare -A person
$ person[name]=”Tae Ng”
8. Create associative array line by line $ person[age]=26
$ person[nationality]=VN
9. Print all keys of associative array $ echo ${!array[@]}
0. Print all values of associative array $ echo ${array[@]}
CONSTANT ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
1. Create a constant $ readonly pi=3.14
2. Use constant $ echo $pi
3. Try to modify constant to see error $ pi=3.1
PART C. Temporary and Environment Variable
ENVIRONMENT VARIABLE ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
$ a=1; b=2; c=3
1. Create temporary variable on current shell $ echo “$a+$b+c” | bc
$ nano ~/.bashrc
~ export a=1
~ export b=2
~ export c=3
2. Create permanent variable in ~/.bashrc ~
~ m=4; n=5; o=6; export m n o
~
~ export x=7 y=8 z=9
$ source ~/.bashrc
$ nano ~/.bashrc
~ export desktop=/home/tae/Desktop
3. Best practice for environment variable $ source ~/.bashrc
$ cd $desktop
PART D. Operators on Linux Shell
SIMPLE OPERATIONS ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
$ nano test.sh
~ echo $(($1 + $2)) #addition
~ echo $(($1 – $2)) #subtraction
~ echo $(($1 * $2)) #multiplication
1. Basic operations ~ echo $(($1 / $2)) #division
~ echo $(($1 % $2)) #remainder
~ echo $(($1 **$2)) #exponentation
$ bash test.sh 5 2
~ x=5 ~ x=5 ~ x=5
~ y=5 ~ y=5 ~ y=5
~ ~ ~
~ ((x++)) ~ ((x+=2)) ~ ((x*=2))
2. Medium operations ~ ((y--)) ~ ((y-=2)) ~ ((y/=2))
~ ~ ~
~ echo $x ~ echo $x ~ echo $x
~ echo $y ~ echo $y ~ echo $y
$ nano compare.sh
~ echo $(($1 > $2)) # 1 if a > b, 0 if a < b
3. Comparisons ~ echo $(($1 < $2)) # 1 if a < b, 0 if a > b
~ echo $(($1 == $2)) # 0 if a ≠ b
$ bash compare.sh 5 2
SIMPLE OPERATIONS (ON INT) ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
1. Greater than > -gt
2. Greater than or equal to >= -ge
3. Less than < -lt
4. Less than or euqal to <= -le
5. Equal to == -eq
6. Not equal to != -ne
OTHER FLAGS ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
1. If there is a file -f
2. If there is a directory -d
3. If the file exists -e
4. If the file exists and size > 0 -s
5. If the file exists and readable -r
6. If the file exists and writable -w
7. Multiple conditions: and &&
8. Multiple conditions: or ||
~ file="/path/to/your/file"
~
~ if [ -f "$file" ]; then
9. Example ~ echo "File exists."
~ else
~ echo "File does not exist."
~ fi
PART E. Control Statements in Bash Scripting
IF STATEMENTS ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
~ x='abc' ~ x=10
~ if [ "$x" == 'abc' ]; then ~ if (($x > 5)); then
~ echo "$x equal to abc" ~ echo True
1. If statement by operator ~ else ~ else
~ echo "$x not equal to abc" ~ echo False
~ fi ~ fi
~ x='abc' ~ x=10
~ if [ "$x" = 'abc' ]; then ~ if [ $x -gt 5 ]; then
~ echo "$x equal to abc" ~ echo True
2. If statement by flag ~ else ~ else
~ echo "$x not equal to abc" ~ echo False
~ fi ~ fi
FOR LOOP ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
~ for i in 1 2 3 4
~ do
1. Simple loop ~ echo $i
~ done
~ for i in {1..10..2}
~ do
2. Number range loop ~ echo $i
~ done
~ for ((i=2;i<10;i+=2))
~ do
3. Three expression syntax loop ~ echo $i
~ done
~ for file in /path/to/files/*
~ do
4. Loop in operating system ~ echo $file
~ done
OTHER LOOPS ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
~ x=1 ~ x="abc"
~ while [ $x -le 7]; ~ case $x in
~ do ~ "abc")
~ echo $x ~ echo "Correct"
~ ((x+=1)) ~ ;;
~ done ~ "xyz")
~ echo "Incorrect"
1. While loop and case statement ~ ;;
~ *)
~ echo "Unknow value"
~ ;;
~ esac
PART F. Functions
FUNCTION ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
~ function function_name { ~ function_name() {
1. Function structure ~ # commands ~ # commands
~ } ~ }
~ convert_c_to_f() {
~ celsius=$1
~ fahrenheit=$(echo "scale=2; ($celsius * 9/5) + 32" | bc)
2. Sample function ~ echo $fahrenheit
~ }
~ convert_c_to_f 25
ARGUMENTS ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
~ print_args() {
~ echo "The first argument is: $1"
~ echo "There are $# argument(s)"
~ for i in $*
1. Pass Arguments into function ~ do
~ echo "argument is: $i"
~ done
~ }
~ print_args abc xyz 123 999
SCOPE ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
~ print_args() { ~ print_args() {
~ first_arg=$1 ~ local first_arg=$1
1. All variable in Bash are global and restrict ~ } ~ }
~ print_args abc xyz 123 999 ~ print_args abc xyz 123 999
~ echo $first_arg ~ echo $first_arg
PART G. Automation with Cron
CRON SYNTAX ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
1. Set up Cronjobs $ crontab -e
* * * * * <command_to_run>
│ │ │ │ │
│ │ │ │ └── Day in week (0 = Sunday)
2. Syntax │ │ │ └──── Month (1–12)
│ │ └────── Day in month (1–31)
│ └──────── Hour (0–23)
└────────── Minute (0–59)
~ 0 7 * * * <command_to_run> ~ */2 * * * * <command_to_run>
~ 30 18 * * * <command_to_run> ~ * */3 * * * <command_to_run>
~ 0 */3 * * * <command_to_run> ~ * * */4 * * <command_to_run>
3. Examples
~ */10 * * * * <command_to_run> ~ * * * */5 * <command_to_run>
~ * 9-17 * * * <command_to_run> ~ * * * * */6 <command_to_run>
~ 10,15 * * * * <command_to_run> ~ * 3 * * */6 <command_to_run>
4. List all Cronjobs $ crontab -l
5. Delete all existed Cronjobs $ crontab -r
EXAMPLE 1 ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
1. Create script $ crontab -e
2. Copy code ~ * * * * * echo "Hello, world! $(date)" >> /home/tae/Desktop/hello.log
4. Create Cronjob $ crontab -e
5. Paste code to Cron ~ * * * * * /home/tae/Desktop/test.sh
EXAMPLE 2 ────────────────────── ⋆⋅☆⋅⋆
──────────────────────
1. Create script $ nano backup_script.sh
~ #!/bin/bash
~
~ SOURCE_DIR="/home/tae/Desktop/data"
~ DEST_DIR="/home/tae/Desktop/backups"
2. Copy code ~
~ TIMESTAMP=$(date +"%Y-%m-%d_%H-%M")
~ BACKUP_NAME="data_backup_$TIMESTAMP.tar.gz"
~
~ tar -czf "$DEST_DIR/$BACKUP_NAME" "$SOURCE_DIR"
3. Give permission to execute script $ chmod +x backup_script.sh
4. Create Cronjob $ crontab -e
5. Paste code to Cron ~ */1 * * * * /home/tae/Desktop/backup_script.sh