# Bash / Bash Script ## Waht is Shell A **Shell** is a command interpreter. Commands can be executable files or built-ins. ## What is Shell Script A **Shell Script** is a plain text file containing a set of various commands. It can be used to automate repetitive tasks on Linux filesystem. ## What is Bash Bash is a common and popular shell. ## shebang ``` bash #!/bin/bash ``` Specify the location of the shell interpreter in our operating system. - on the first line - no any space ## echo ``` bash echo [option] [string] ``` Display the standard output by passing the arguments. ## Comment ### Single Line Comment ``` bash # This is a single-line comment in Bash Script. ``` ### Multi Line Comment ``` bash <<COMMENTS COMMENTS : ' ' <<COMMENTS This is a multi-line comment in Bash Script. COMMENTS : ' This is also a multi-line comment in Bash Script. ' ``` ## Quote Used to handle texts and filenames with a space character. - content within the quotes should be considered as a single item - shell variable expansion will only work with double-quotes. ``` bash #!/bin/bash name="asdf" echo "$name" echo '$name' ``` > asdf > $name ## Variable ``` bash name=Joey echo $name ``` The containers which store data. - case sensitive - untyped - no need of using any quotes to define a variable with single character value - no whitespace when doing assignment ### System-Defined Variables ``` bash echo $HOME echo $PWD ``` - BASH - shell name - BASH_VERSION - shell version - HOME - home directory - PWD - current working directory ## Command Line Arguments ``` ./script.sh arg1 arg2 arg3 ``` - $0 - the name of the script - $1~$9 - the first 9 arguments - $# - number of arguments - $* - all arguments (as one word) - $@ - all arguments (as array) ``` bash echo $1 $2 ``` ## Command Substitution ``` bash var=$(command_name) echo $var var=`command_name` echo $var ``` It takes the output of the Bash command, stores in a variable, and display back with echo. ## Read User Input ``` bash read variable_name read -p "name:" variable_name # same prompt read -sp "passward:" variable_name # silent mode read -a array_name # read an array ``` ## Arithmetic Operations ``` bash Sum=$((10 + 3)) ((Sum=10 + 3)) ``` ### Operators - \+ - \- - \* - \/ - \*\* - \% - \+= - \-= - \*= - \/= - \%= ### Let Perform arithmetic operations ``` let "z=$((10 + 3))" ``` ### Backticks Similar to "let", but it does not save the result to a variable. ``` bash `expr $a + $b` ``` ## If ``` test condition [condition] [[condition]] ``` ``` bash if [ condition ] then statements fi if [ condition ]; then statements else statements fi if [ condition ]; then statements elif [ condition ]; then statements else statements fi ``` ### Operators - !EXPRESSION - check if EXPRESSION is false - \-n STRING - check if the length of STRING is greater than zero - \-z STRING - check if the length of STRING is zero - STRING1 == STRING2 - STRING1 != STRING2 - INTEGER1 -eq INTEGER2 - INTEGER1 -gt INTEGER2 - INTEGER1 -ge INTEGER2 - INTEGER1 -lt INTEGER2 - INTEGER1 -le INTEGER2 - \-d FILE - check if FILE exists and it is a directory - \-e FILE - check if FILE exists ## Case ``` bash case expression in pattern_1) statements ;; pattern_2) statements ;; pattern_3|pattern_4|pattern_5) statements ;; pattern-n) statements ;; *) statements ;; esac ``` ## Loop ### For ``` bash for variable in list do statements done for (( expression1; expression2; expression3 )) do statements done ``` ### While ``` bash while [ expressions ]; do commands done ``` ### Until ``` bash until [ expressions ]; do commands done ``` ## String ### Operator - str1 = str2 - str1 != str2 - str1 < str2 (less than) - str1 > str2 (greater than) - -n str (length > 0) - -z str (length == 0) - ${#str} (return length) ## Pattern Matching ### Wildcard - \* - match zero or more characters - ? - match any single character - [...] - match any of the characters in a set - ?(patterns) - match zero or one occurrences of the patterns - \*(patterns) - match zero or more occurrences of the patterns - +(patterns) - match one or more occurrences of the patterns - @(patterns) - match one occurrence of the patterns - !(patterns) - match anything that doesn't match one of the patterns ### Curly braces ``` bash # cat log.txt log.csv cat log.{txt,csv} # cat all *.py and *.sh files cat *{.py,.sh} ``` ## Substitution - ${foo%suffix} - remove suffix - ${foo#prefix} - remove prefix - ${foo%%suffix} - remove long suffix - ${foo##prefix} - remove long prefix - ${foo/from/to} - replace first match - ${foo//from/to} - replace all - ${foo/%from/to} - replace suffix - ${foo/#from/to} - replace prefix ## Function ``` bash # Definition function_name () { statements } # Calling function_name ``` ### Passing Arguments ``` bash # Calling with arguments function_name () { echo $1 echo $2 echo $3 } function_name arg1 arg2 arg3 ``` ### Variable Scope - variables are defined as global variables by default ``` bash local name=Joey ``` ## Array ### Initialization ``` bash arr[0] = value_0 arr[1] = value_1 arr[2] = value_2 ``` ``` bash arr=(value_0 value_1 value_2) ``` ### Array Length ``` bash ${#arr[@]} ``` ### Loop through the Array ``` bash for ele in ${arr[@]} do echo $ele done for i in ${!arr[@]} do echo $i ":" ${arr[$i]} done ``` ### Adding Element ``` bash arr+=(value) ``` ### Remove Element ``` bash unset arr[index] ``` ### Delete Array ``` bash unset arr ``` ### Slice Array ``` bash arr_slice=(${arr[@]:m:n}) ``` ### Check If Files Exist ``` bash FILE=/etc/resolv.conf if [-f "$FILE"]; then echo "$FILE exists." fi ``` - \-d FILE: True if the FILE exists and is a directory. - \-e FILE: True if the FILE exists and is a file, regardless of type (node, directory, socket, etc.). - \-f FILE: True if the FILE exists and is a regular file (not a directory or device). - \-x FILE: True if the FILE exists and is executable. ### Stdio Redirection - \>: redirect output (default 1>) - \<: redirect input (default 0<) - 0: stdin - 1: stdout - 2: stderr - &>: 2>&1 ``` bash # redirect the stderr to file command 2> file # '> file' redirect the stdout to file # then '2>&1' redirect the stderr to stdout. command > file 2>&1 # redirect both stdout/stderr to file command &> file command 2>&1 > file ``` ### Piping redirect the stdout of the former program as the stdin of the latter program ``` bash # count the number of particular files ls *.txt | grep test | wc -l # sort the content of a file $ cat file.txt | sort | cat > sortedFile.txt # read the specific line of a file cat file.txt | head -3 | tail -1 ``` #### xargs execute a command using STDIN as arguments. ``` bash # list all contents of files in the current dir ls | xargs cat ```