Linux & Bash
Introduction to Linux
[Hide]Vim
[Hide]vim-nox
, which provides support for scripting with various languages.
sudo apt install vim-nox apt show vim-noxNow we should be able to go into our shell and type
vim
to open the text editor. What shows up is a buffer, which is just some free memory that we can type in. This can be a new file that is not saved or an existing file that we are editing. When opening Vim, we are in command mode, which allows to run the following commands:
:q
or quit without saving :q!
i
or at the end SHIFT + A
ESC
:w test.txt
, where w
stands for "write" and test.txt
is the file name:w
u
dd
:
, you can press the up arrow to get your previous commands.
Bash Scripting
[Hide]#!/bin/bash
a the top, known as a shebang. From this we can enter in the commands that we would type as below.
#!/bin/bash ls pwd echo "Hello World!"Now we can save it as
myscript.sh
(the suffix is not really needed if we have the shebang, but for clarity). Before we can run it, we must turn it into an executable with the command
chmod +x myscript.shBy going into the working directory and running
ls --color
, we can color code all the files/directories, where green stands for executables and blue are directories. Now we can run it by
./myscript.sh
(base) mbahng@xps-15-9500:~/Desktop$ myName="Muchang" (base) mbahng@xps-15-9500:~/Desktop$ echo $myName Muchang (base) mbahng@xps-15-9500:~/Desktop$ echo myName myNameWe must have the dollar sign since there are no key words in bash. Unlike Python, where certain words like if, else, while, etc. are reserved for certain commands and therefore cannot be used as variables, we don't have this control in bash, so we need the $. Also, if we declare a variable, it is tied to the session, so closing the terminal will delete all references. Now we can simply apply this to a bash script. Below, we want to show one more property that distinguishes single quotes and double quotes. We want to use double quotes since single quotes will output as raw strings.
#!/bin/bash myName="Muchang" myAge="21" echo "Hello, my name is $myName." echo 'Hello, my name is $myName.' echo "I am $myAge years old."and running it gives
(base) mbahng@xps-15-9500:~/Desktop$ ./myscript.sh Hello, my name is Muchang. Hello, my name is $myName. I am 21 years old.Now to set the variable equal to the output of a command, like
pwd
or ls
, we can just store it inside a paranthesis.
(base) mbahng@xps-15-9500:~/Desktop$ files=$(pwd) (base) mbahng@xps-15-9500:~/Desktop$ echo $files /home/mbahng/DesktopWe can use this in combination with the
date
command to create maybe a script that greets us and returns the current time:
#!/bin/bash myName="Muchang" echo "Hello, $myName." echo "Today's date is $(date)" (base) mbahng@xps-15-9500:~/Desktop$ ./myscript.sh Hello, Muchang. Today's date is Thu Jun 29 03:32:13 PM EDT 2023There are special types of variables, called environment variables, which are all in uppercase. Due to this reason, it is important to conventionally keep your own variables to not be all uppercase, as they may get confused with the environment variables. We can view all of them with the
env
command.
(base) mbahng@xps-15-9500:~/Desktop$ env SHELL=/bin/bash SESSION_MANAGER=local/xps-15-9500:@/tmp/.ICE-unix/80970,unix/xps-15-9500:/tmp/.ICE-unix/80970 QT_ACCESSIBILITY=1 COLORTERM=truecolor XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg SSH_AGENT_LAUNCHER=gnome-keyring XDG_MENU_PREFIX=gnome- ...These are always initialized and can be accesssed and so we do not need to manually reference them.
(base) mbahng@xps-15-9500:~/Desktop$ echo $HOME /home/mbahng (base) mbahng@xps-15-9500:~/Desktop$ echo $USER mbahng
30 + 10
in the Python shell. However, in Bash, we need to use the evaluate expression command, abbreviated expr
, where we can do addition, subtraction, multiplication (which needs the escape character since *
is a wildcard), and integer division.
(base) mbahng@xps-15-9500:~$ expr 30 + 10 40 (base) mbahng@xps-15-9500:~$ expr 30 - 10 20 (base) mbahng@xps-15-9500:~$ expr 30 \* 10 300 (base) mbahng@xps-15-9500:~$ expr 30 / 10 3 (base) mbahng@xps-15-9500:~$ expr 30 / 8 3Note that the spaces between the operation and the numbers is important.
(base) mbahng@xps-15-9500:~$ expr 30+10 30+10Again, we can store these integers in variables and operate on them.
(base) mbahng@xps-15-9500:~$ myNum1=100 (base) mbahng@xps-15-9500:~$ echo $myNum1 100 (base) mbahng@xps-15-9500:~$ expr $myNum1 + 50 150 (base) mbahng@xps-15-9500:~$ myNum2=88 (base) mbahng@xps-15-9500:~$ expr $myNum1 - $myNum2 12
fi
.
#!/bin/bash myNum=200 if [ $myNum -eq 200 ] then echo "The condition is true." else echo "The variable does not equal 200." fiLet us clarify some more math operators:
!
means not. -eq
) and not equals (-ne
). -gt
) and less than (-lt
). myfile
within a directory, we can write
#!/bin/bash if [ -f ~/myfile ] then echo "The file exists" else echo "The file does not exist" fiWe can do the same for directories by simply replacing the
-f
with a -d
.
?
variable, which actually tells us whether the input command was a success or failure. The variable is initialized every time we enter in a command.
(base) mbahng@xps-15-9500:~/Desktop$ ls -l /misc ls: cannot access '/misc': No such file or directory (base) mbahng@xps-15-9500:~/Desktop$ echo $? 2Basically, an exit code of 0 means that the command was successful, and anything other than 0 means a failure. The reason we want these exit codes is that when we automate tasks, we want scripts to run based on the exit codes of our original scripts. That is, if we get an exit code of 0, then this may trigger another bash script that emails the system administrator to let them know that something was wrong. We can create an example script that installs a package using apt as such:
#!/bin/bash package=htop sudo apt install package if [ $? -eq 0 ] then echo "The installation of $package was successful." echo "The new command is available here:" which $package else echo "$package failed to install." fiTo manually force the exit code to be a certain number, we can do so as below. Note that since this is an exit code the script will end right at the line where we call
exit
. This is not like a break statement, where it breaks out of a loop to continue on the script. It literally terminates the script right here.
#!/bin/bash sudo apt install notexist exit 0
>>
symbol.
mbahng@xps-15-9500:~/Desktop$ apt list >> packages.txt
#!/bin/bash myVar=1 while [ $myVar -le 10 ] do echo $myVar # Increment by 1 myVar=$(( $myVar + 1)) # Sleep for 0.5 seconds sleep 0.5 doneThe syntax for a for loop within a range of number is:
#!/bin/bash for i in {1..10} do echo $i sleep 1 done echo "This is outside of the for loop. "We can also iterate over all files with a
.log
suffix in the logfiles
directory and compresses them for using tar.
#!/bin/bash for file in logfiles/*.log do tar -czvf $file.tar.gz $file done
/usr/local/bin
and to remove the .sh
suffix. There are two reasons for this:
/usr/local/bin
is in the PATH environment variable, so your script can be accessed directly.