Post

ShellScripts

Let's study ShellScripts.

ShellScripts

Shebang

The first line written in a script defines which shell will be used to execute the script when it runs.
There are multiple versions of shells.

  • sh: The original Unix shell (Bourne shell), released in 1977.
  • ksh: Also known as the Korn shell, developed by David Korn in 1983 as an extension of sh.
  • csh: Created in 1978 at the University of California, Berkeley, based on the C programming language.
  • bash: Developed by Brian Fox in 1987, it is mostly compatible with sh.

The first line is a declaration that the script will be executed using the standard shell, bash.
This type of shell declaration is called a Shebang.

1
2
#!/usr/bin/bash
echo $(which bash) # /usr/bin/bash
1
/usr/bin/bash

File Permission Settings and Execution

1
2
3
4
5
6
7
8
9
10
11
12
# Case1)
$ vi mytest.sh
# #!/usr/bin/bash
# echo $(which bash)
$ chmod +x mytest.sh or chmod 755 mytest.sh
$ ./mytest.sh

# Case2)
$ vi mytest.sh
# #!/usr/bin/bash
# echo $(which bash)
$ bash mytest.sh # When executed with `bash`, it can run without granting execute permissions.
1
$ /usr/bin/bash

Shell Variable Declaration

basic

There are various types of variables, such as local variables, global variables, environment variables, reserved variables, and parameters.

  • Variables are case-sensitive.
  • Variable names can include numbers, but cannot start with a number.
  • All values are stored as strings in variables.
  • Data types are not specified when declaring variables (e.g., int number, char names[10] are not used), meaning you can assign any value.
  • When using a variable, prefix its name with the special character $ (e.g., echo ${myname} or echo $myname).
  • When assigning a value to a variable, do not use $ (e.g., myname=ds2man).
  • There should be no spaces around the = sign when creating a variable (e.g., myname="abcd").
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## $ vi mytest.sh

#!/usr/bin/bash

myname="ds2man"
phone_no1=01011233342 # type is string!
phone_no2="01011233342" # type is string!

echo $myname
echo "my name is ${myname}"
echo my name is ${myname}
printf "%d vs %s\n" $phone_no1 $phone_no1 # not %d, %s is collect
printf "%d vs %s\n" $phone_no2 $phone_no2 # not %d, %s is collect
printf "=========\n"
unset myname # initialize variable
echo my name is ${myname}
1
2
3
4
5
6
7
8
$ ./mytest.sh
ds2man
my name is ds2man
my name is ds2man
136656610 vs 01011233342
136656610 vs 01011233342
=========
my name is

Environment Variable

In a shell script, prefixing a variable name with export sets it as an environment variable, making it accessible in child scripts.
However, when using environment variables, be careful not to use variable names that conflict with predefined reserved variables in the system.

1
2
3
4
5
## $ vi mytest.sh

#!/usr/bin/bash

echo ${myname}
1
2
3
$ export myname="ds2man is datascientist"
$ ./mytest.sh
ds2man is datascientist

Global and Local Variable

Variables declared in the shell are, by default, global variables. However, local variables can be used only within functions, and to declare them, you need to prefix the variable name with local.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
## $ vi mytest.sh

#!/usr/bin/bash

mystring="ds2man study" # global variable

function string_test() {
    # A variable is recognized as a local variable only when prefixed with `local`.  
    # If `local` is omitted, it will overwrite the global variable instead.
    local mystring="ds2man lecture"
    echo string_test, ${mystring}
}


string_test # string_test() is error...
echo out of string_test, ${mystring}

# 변수 초기화
unset string
1
2
3
$ ./mytest.sh
string_test, ds2man lecture
out of string_test, ds2man study

Control Structures

Shell scripting allows us to control the flow of execution using conditional and loop statements, just like in most programming languages. we’ll go over five key control structures: if, case, for, for-in, and while, with clear examples for each.

if Statement

Before diving into the if statement, let’s take a look at comparison operators and logical operators

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# comparison operators
value1 -eq value2     # equal, Note. not ==
value1 -ne value2     # not equal, Note. not !=
value1 -lt value2     # less than, Note. not <
value1 -le value2     # less than or equal, Note. not <=
value1 -gt value2     # greater than. not >
value1 -ge value2     # greater than or equal, Note. not >=

string1 = string2        # string1 and string2 are equal (just one '=' works like in SQL)
string1 == string2       # string1 and string2 are equal
string1 != string2       # string1 and string2 are not equal
-z string                # true if the string is null (zero length)
-n string                # true if the string is not null
string == pattern        # true if the string matches the pattern
string != pattern        # true if the string does not match the pattern

# logical operators
condition1 && condition2     # AND
condition1 || condition2     # OR
!condition                   # condition is not true  
true                         # always true  
false                        # always false  

Note. Double Parentheses (( expression ))
An arithmetic or comparison expression can be placed inside the expression.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## $ vi mytest.sh

#!/usr/bin/bash

# The `read` command is used to receive input from the user and store it in a variable.
read -p "Enter a number: " num1 num2

if [ ${num1} -lt ${num2} ]; then 
	echo "${num1} is less then ${num2}"
elif [ ${num1} -gt ${num2} ]; then 
	echo "${num1} is greater then ${num2}"
else
	echo "${num1} is equal to ${num2}"
fi

echo "Double Parentheses"
if (( ${num1} < ${num2} )); then 
	echo "${num1} < ${num2}"
elif (( ${num1} > ${num2} )); then 
	echo "${num1} > ${num2}"
else
	echo "${num1} is equal to ${num2}"
fi
1
2
3
4
5
$ ./mytest.sh
Enter a number: 3 5
3 is less then 5
Double Parentheses
3 < 5

case Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## $ vi mytest.sh

#!/bin/bash

read -p "Choose an option (a/b/c): " option

case $option in
  a)
    echo "You selected option A."
    ;;
  b)
    echo "You selected option B."
    ;;
  c)
    echo "You selected option C."
    ;;
  *)
    echo "Invalid input."
    ;;
esac
1
2
3
$ ./mytest.sh
Choose an option (a/b/c): c
You selected option C.

for Loop Statement

1
2
3
4
5
6
7
8
## $ vi mytest.sh

#!/usr/bin/bash

for ((i=1; i<=5; i++))
do
  echo "Current number: $i"
done
1
2
3
4
5
6
$ ./mytest.sh
Current number: 1
Current number: 2
Current number: 3
Current number: 4
Current number: 5

for-in Loop Statement

1
2
3
4
5
6
7
8
9
10
## $ vi mytest.sh

#!/usr/bin/bash

FRULTS=("apple" "banana" orange)
# Note. `[@]` splits each element of the array into separate individual arguments.
for fruit in "${FRULTS[@]}" # for fruit in ${FRULTS[@]} is same!
do
  echo "Fruit: $fruit"
done
1
2
3
4
$ ./mytest.sh
Fruit: apple
Fruit: banana
Fruit: orange

while Loop Statement

1
2
3
4
5
6
7
8
9
10
11
## $ vi mytest.sh

#!/usr/bin/bash

count=1

while (( $count <= 5 ))
do
  echo "Count: $count"
  ((count++))
done
1
2
3
4
5
6
$ ./mytest.sh
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
This post is licensed under CC BY 4.0 by the author.