Linux Basics
I've been learning Linux for the past couple of weeks, I've learned the fundamentals of Linux and some of the Linux commands. Inspired by my lecture notes, I decided to write a blog to share my newly acquired knowledge.
Linux is quite fascinating. Now that I've been learning and using it more often, I sometimes find it better than Windows. Linux is the most common and most loved platform used for development. Many of the new DevOps tools are developed and used on the Linux environment first before they are made available for Windows.
There are different flavors of Linux such as Ubuntu, Redhat Enterprize Linux, CentOS etc. I've used CentOS Linux while learning.
Linux systems have both CLI and GUI interfaces. The text-based CLI that helps you run commands to interact with the OS is called the Linux shell. The different types of Linux shells are :
Bourne Shell (sh shell)
C Shell (csh or tcsh)
Z Shell (zsh)
Bourne Again Shell (bash)
Package Managers
Package managers help you install various software on the Linux system. We will have to install various software such as web servers, database servers, DevOps tools or dependent software and most of these are installed using package managers. They simplify the process by automatically handling dependencies and resolving conflicts. CentOS, for instance, employs an RPM-based package manager known as RPM (Red Hat Package Manager).
Software is packaged into a bundle(package) using the extension .rpm ( ex: telnet.rpm)
To Install Package ->
rpm -i telnet.rpm
To Uninstall Package ->
rpm -e telnet
To Query Package ->
rpm -q telnet.rpm
To list all the installations ->
rpm -qa telnet.rpm
One limitation of RPM is that it does not automatically manage dependencies. RPM requires you to point it to the exact location where the RPM package is available and then install that package on the system. RPM does not care about any dependencies the package may have i.e., RPM does not install the other dependent software. Hence to resolve this issue and ensure the dependencies are also installed, we need a single command that queries the package, finds its location and installs the package as well as all its dependencies. Here's when YUM comes into the picture.
YUM is a high-level package manager that uses RPM underneath. Running a single yum install command installs the package and all of its dependent packages. Example: yum install ansible
-> This command installs Ansible and its dependent packages. YUM takes care of locating the necessary packages and their dependencies, simplifying the installation process significantly.
How YUM works?
YUM searches software repositories that act as warehouses(storage units) containing rpm packages (rpm package files). These repos can be local or in a remote location ( a secure server in your enterprise or available publicly on the internet). YUM still makes use of the rpm packages underneath. When you try to install a package using YUM, it searches these repos, finds the required packages and their dependencies and installs all of them in the right order.
How does YUM find where a particular package is located?
The information about a repository is in a configuration file at path: /etc/yum.repos.d directory. Every OS comes bundled with its own set of repositories from which you can install a lot of commonly used software and tools. At times, the default set of repositories may not have the software you need or the latest version of the software you need. In that case, you will have to configure additional repositories so that YUM can find those packages. Instructions to configure those additional repos are usually made available along with the software itself. To display the list of repositories available on a system, run the command: yum repolist
The command ls /etc/yum.repos.d
displays the files where these repositories are configured. If you open one of these files, you will find the URL from which the software can be installed. If you visit this URL, you will see the rpm files that YUM will eventually download and install on your local system with the rpm utility.
When we use an existing repo, it has an older version of the system. The latest version of the software can be installed from instructions available in the documentation of the software itself.
to list the available packages run ->
yum list package_name
to install a specific version of a package ->
yum install package_name version
to remove a package ->
yum remove package_name
to list all available versions of a package->
yum --showduplicates list package_name
Services
Services in Linux help you configure the software to run in the background and make sure they run all the time automatically when the servers are rebooted as well as follow the right order of startup. When any software that runs as a service in the background is installed, they're automatically configured as a service on the system.
systemctl is the command line utility used to manage services on a systemd managed server. Another command is the service command which acts the same service service_name start
This service command uses the systemctl utility underneath.
commands:
To start a service -
systemctl start service_name
To stop a service -
systemctl stop service_name
To check the status of service -
systemctl status service_name
To configure a service to start at startup -
systemctl enable service_name
To configure a service to not start at startup -
systemctl disable service_name
How do you configure a program or software as a service?
for example, say we have a simple Python program. its path: /usr/bin/python3/opt/code/my_app.py
Now, we want to configure this program as a service. We want this program to run as a service so that when you run the systemctl start command, it starts and the systemctl stop command stops it. We also want to configure the program to automatically start when the system boots up and even automatically restart incase the program or application crashes.
The systemctl command line utility is used to manage the systemd services. So we must configure our program as a systemd service. A systemd service is configured using a systemd unit file. These files are located at /etc/systemd/system path. Let's create a unit file at this path. The unit file must be named with the name you eventually want your service to be known as. we use the ".service" extension. for example, my_app.service
The internal structure of unit files is organized with sections which are indicated by a set of square brackets "[ ]" enclosing the section name. Each section extends until the beginning of the subsequent section or until the end of the file. Within these sections, the unit behavior and data are defined through directives.
Define a section called Service and provide a directive named ExecStart. This is where you specify the commands that you will be using to run the application.
Run the systemctl daemon-reload
command to let the system know that there is a new service configured. Now, we can start the service by the command systemctl start my_app
and run the systemctl status my_app
which lists that the service is in an active and running state.
we can now test this by performing a curl operation on a port of the local host by the command : curl http://localhost : 5000
We have now configured our application to run as a service and we are now able to start and stop as required.
How do we configure our application to automatically run when the system is rebooted?
We configure it in the unit file. The unit configuration file has many other options(sections), one of them is the Install section. In this, we configure a service to run after a particular service that runs at boot-up. We do this by the WantedBy directive and specify the service after which our application(service) is to be started. After this, we configure by using the systemctl enable my_app
command.
We can also provide additional data about the service such as its description. For that, we add a new section to the file called Unit and use the description directive.
If your application has other dependencies such as commands or scripts that are to be run before or after the starting of the application, then add the ExecStartPre and the ExecStartPost directives and specify the commands or scripts to be run respectively.
Also, specify the Restart directive and set it to "always" to automatically restart the service if it crashes.
The Unit file for our example i.e., the my_app service would look something like this:
my_app.service
[Unit]
Description=My Python web application
[Service]
ExecStart=/usr/bin/python3/opt/code/my_app.py
ExecStartPre=/opt/code/configure_db.sh
ExecStartPost=/opt/code/email_status.sh
Restart=always
[Install]
WantedBy=multi_user.target
Some of the resources from where I've learned Linux :