Programming/Bash

From Dev Wiki
< Programming
Revision as of 09:08, 7 October 2020 by Brodriguez (talk | contribs) (Document functions)
Jump to navigation Jump to search

Bash is primarily a Linux scripting language, but it works on all versions of Windows as well, if used through git.

File Start

Unless you have explicit reason for otherwise, essentially all bash files can safely start with the line:

#!/usr/bin/env bash

It essentially tells your script what interpreter to use when executing the file.

Comments

Inline Comments

# This is an inline comment.

Block Comments

Block level comments don't truly exist in Bash.

However, there is a hackish way to implement them anyways, according to https://stackoverflow.com/a/43158193 { warn | It's recommended to use multiple inline comments instead, as this may not always work with all systems. }

: '
This is a block comment.
Comment line 2.
Another block comment line.
'

Variables

For variable definition, note that spacing is important. Spacing around the equals sign will break the assignment.

Variable Definition

a_bool=true
b_bool=false
my_var_1="This is "
my_var_2="a string."

Variable Usage

echo "Printing variable values."
echo $a_bool
echo $b_bool
echo ${my_var_1}${my_var_2}

Passing Variables into the Script

It's possible to pass variables directly from the command line into a given bash script. To do this, type the command to execute the script, followed by all the args you wish to pass in.

For example, if your script name is my_script.sh, then you might have the following:

./my_script.sh test 5

This will pass in the arguments of "test" and "5" into your script.

Accessing Variables Passed into the Script

You access passed variables via the dollar sign, followed by the argument number.

For example, in the above scenario, we passed in values "test" and "5" as the first and second arg respectively. To access them, we could use:

echo $0    # Prints out our script name, "my_script.sh".
echo $1    # Prints out "test".
echo $2    # Prints out "5".


If Statements

Basic If

if [[ $x == $y ]]
then
    # Logic if true.
fi

Full If

if [[ $x == $y ]]
then
    # Logic for "if" true.
elif [[ $x && ($y || $z) ]]
then
    # Logic for "else if" true.
else
    # Logic for false.
fi

File and Folder Checks

For a full list of built-in args to check file and folder status, see https://www.gnu.org/software/bash/manual/bash.html#Bash-Conditional-Expressions


For Loops

for <loop_variable> in $<my_iterable_object>
do
    # Logic to execute on each loop.
done

For example:

for item in $my_list
do
    echo $item
done


Functions

function <function_name> () {
    # Function logic here.
}

Passing Parameters

Passing variables into functions in Bash is a bit...obtuse, for lack of a better word.

Essentially, each function is almost treated as a new instance of a bash script. So functions use the same syntax to pass variables into the script.

For example, if we have `test_function` and we want to pass two variables, then the code may look like this:

 function test_function () {
    var_1=$1
    var_2=$2
}

To call this function, we would have code like this:

some_var_1="test"
some_var_2=5
...
test_function $some_var_1 $some_var_2


String Manipulation

See https://stackoverflow.com/a/14703709

With bash, it's possible to dynamically trim strings, based on regex matches.
The syntax is:

# Trim shortest match from beginning.
${<string_value>#<regex>}

# Trim longest match from beginning.
${<string_value>##<regex>}

# Trim shortest match from end.
${<string_value>%<regex>}

# Trim longest match from end.
${<string_value>%%<regex>}


For example, if you have a string of

file_name="/home/user/my_dir/my_dir/my_file.tar.gz"

Then you can do the following manipulations:

# Get the full file extension.
# Outputs "tar.gz"
${file_name#*.}

# Get the last part of the file extension.
# Outputs "gz"
${file_name##*.}

# Get the full file name, including file extension.
# Outputs "my_file.tar.gz"
echo "b: ${file_name##*/}

# Get parent of current directory.
# Outputs "/home/user/my_dir/"
${file_name%my_dir/*}

# Get grandparent of current directory.
# Outputs "/home/user/"
${file_name%%my_dir/*}