<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Angel Oduro-Temeng Twumasi</title>
    <description>The latest articles on DEV Community by Angel Oduro-Temeng Twumasi (@angelotheman).</description>
    <link>https://dev.to/angelotheman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F509046%2F9e4225de-aefc-4980-819f-cd09bd7efbf9.jpg</url>
      <title>DEV Community: Angel Oduro-Temeng Twumasi</title>
      <link>https://dev.to/angelotheman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/angelotheman"/>
    <language>en</language>
    <item>
      <title>How to Migrate Azure Snapshots with Ease: Single and Multiple Scenarios</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Thu, 12 Dec 2024 14:02:42 +0000</pubDate>
      <link>https://dev.to/angelotheman/how-to-migrate-azure-snapshots-with-ease-single-and-multiple-scenarios-5519</link>
      <guid>https://dev.to/angelotheman/how-to-migrate-azure-snapshots-with-ease-single-and-multiple-scenarios-5519</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Azure snapshots are point-in-time backups of managed disks. They are mainly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating backups for disaster recovery.&lt;/li&gt;
&lt;li&gt;Migrating disk data across different subscriptions or tenants.&lt;/li&gt;
&lt;li&gt;Creating new managed disks from existing snapshots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, manually handling snapshot migration, especially across tenants or subscriptions, can be tedious. Another point to note is that, snapshots could be very large depending on the size of the Virtual Machine(VM) it was created from.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll show how to migrate Azure snapshots efficiently; whether it’s a one-time task or handling multiple snapshots in bulk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Migrate Snapshots?
&lt;/h2&gt;

&lt;p&gt;There are a couple of reasons why you would want to migrate your snapshot to a different tenant. These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consolidation of services and licenses to improve efficiency and reduce expenses.&lt;/li&gt;
&lt;li&gt;Mergers and Acquisitions of companies hence the need for a centralized tenant.&lt;/li&gt;
&lt;li&gt;Ensuring backups for the snapshots in another tenant.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access permissions&lt;/strong&gt;: Access permissions to both source and destination snapshots and storage accounts respectively.&lt;/li&gt;
&lt;li&gt;Destination storage and container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Information&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Subscription ID of source account.&lt;/li&gt;
&lt;li&gt;Resource group name containing the snapshot.&lt;/li&gt;
&lt;li&gt;Storage name and access key for the destination.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Migrating a Single Snapshot
&lt;/h2&gt;

&lt;p&gt;Follow these steps to migrate a single snapshot&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Generate Shared Access Signature (SAS) for the snapshot.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az snapshot grant-access &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--resource-group&lt;/span&gt; &amp;lt;resource-group-name&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;snapshot-name&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--duration-in-seconds&lt;/span&gt; 3600 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;accessSas] &lt;span class="nt"&gt;-o&lt;/span&gt; tsv
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This generates a SAS URL for the snapshot, valid for the specified duration (3600 seconds in this case).&lt;/p&gt;

&lt;p&gt;Here are the parameters explained,&lt;br&gt;
&lt;code&gt;resource-group-name&lt;/code&gt; :  Replace this with the resource group name which has the snapshot.&lt;br&gt;
&lt;code&gt;snapshot-name&lt;/code&gt;: Replace this with the name of the snapshot.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy snapshot to the Destination.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az storage blob copy start &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--destination-blob&lt;/span&gt; &amp;lt;destination-file-name&amp;gt;.vhd &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--destination-container&lt;/span&gt; &amp;lt;container-name&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--account-name&lt;/span&gt; &amp;lt;storage-account-name&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--account-key&lt;/span&gt; &amp;lt;storage-account-key&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--source-uri&lt;/span&gt; &amp;lt;sas-url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Parameters explained,&lt;br&gt;
&lt;code&gt;destination-file-name&lt;/code&gt;: Give your it a name of your choice, for example &lt;code&gt;mysnapshot.vhd&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;storage-account-name&lt;/code&gt;: Storage account name of destination tenant.&lt;br&gt;
&lt;code&gt;storage-account-key&lt;/code&gt;: &lt;a href="https://learn.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal" rel="noopener noreferrer"&gt;Access key&lt;/a&gt; of the storage account.&lt;br&gt;
&lt;code&gt;sas-url&lt;/code&gt;: SAS Uri generated in STEP 1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Migrating Multiple Snapshots
&lt;/h2&gt;

&lt;p&gt;Now, let’s automate the migration for multiple snapshots with a Bash script. This approach is perfect for those managing multiple snapshots across large environments.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create an empty file.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;transfer_script
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the file.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim transfer_script
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add these to the file.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Azure subscription ID&lt;/span&gt;
&lt;span class="nv"&gt;subscriptionId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-subscription-id"&lt;/span&gt;

&lt;span class="c"&gt;# Resource group containing snapshots&lt;/span&gt;
&lt;span class="nv"&gt;resourceGroupName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-resource-group"&lt;/span&gt;

&lt;span class="c"&gt;# SAS expiry duration (seconds)&lt;/span&gt;
&lt;span class="nv"&gt;sasExpiryDuration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3600

&lt;span class="c"&gt;# Destination storage account and key&lt;/span&gt;
&lt;span class="nv"&gt;storageAccountName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-storage-account"&lt;/span&gt;
&lt;span class="nv"&gt;storageAccountKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-storage-key"&lt;/span&gt;

&lt;span class="c"&gt;# Destination container name&lt;/span&gt;
&lt;span class="nv"&gt;storageContainerName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"snapshots"&lt;/span&gt;

&lt;span class="c"&gt;# Snapshots array: ["snapshot-name destination-file-name"]&lt;/span&gt;
&lt;span class="nv"&gt;snapshots&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
    &lt;span class="s2"&gt;"&amp;lt;snapshot1&amp;gt; &amp;lt;snapshot1.vhd&amp;gt;"&lt;/span&gt;
    &lt;span class="s2"&gt;"&amp;lt;snapshot2&amp;gt; &amp;lt;snapshot2.vhd&amp;gt;"&lt;/span&gt;
    &lt;span class="s2"&gt;"&amp;lt;snapshot3&amp;gt; &amp;lt;snapshot3.vhd&amp;gt;"&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Set the Azure subscription&lt;/span&gt;
az account &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--subscription&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$subscriptionId&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Loop through each snapshot and migrate&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;snapshot &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;snapshots&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Extract snapshot name and destination file name&lt;/span&gt;
    &lt;span class="nv"&gt;snapshotName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$snapshot&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;destinationVHDFileName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$snapshot&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Processing snapshot: &lt;/span&gt;&lt;span class="nv"&gt;$snapshotName&lt;/span&gt;&lt;span class="s2"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$destinationVHDFileName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;# Generate SAS URL&lt;/span&gt;
    &lt;span class="nv"&gt;sas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;az snapshot grant-access &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--resource-group&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resourceGroupName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$snapshotName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--duration-in-seconds&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sasExpiryDuration&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;accessSas] &lt;span class="nt"&gt;-o&lt;/span&gt; tsv&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sas&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Failed to generate SAS for &lt;/span&gt;&lt;span class="nv"&gt;$snapshotName&lt;/span&gt;&lt;span class="s2"&gt;. Skipping..."&lt;/span&gt;
        &lt;span class="k"&gt;continue
    fi&lt;/span&gt;

    &lt;span class="c"&gt;# Copy to destination&lt;/span&gt;
    az storage blob copy start &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--destination-blob&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$destinationVHDFileName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--destination-container&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$storageContainerName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--account-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$storageAccountName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--account-key&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$storageAccountKey&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--source-uri&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sas&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Successfully copied &lt;/span&gt;&lt;span class="nv"&gt;$snapshotName&lt;/span&gt;&lt;span class="s2"&gt; to &lt;/span&gt;&lt;span class="nv"&gt;$destinationVHDFileName&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Failed to copy &lt;/span&gt;&lt;span class="nv"&gt;$snapshotName&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
    &lt;span class="k"&gt;fi
done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Extra parameters explained&lt;/p&gt;

&lt;p&gt;&lt;code&gt;snapshot1&lt;/code&gt; and &lt;code&gt;snapshot1.vhd&lt;/code&gt; are the names of the snapshot in the source file and how you would want to name them at the destination respectively. Do this for all.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Press &lt;code&gt;ESC&lt;/code&gt;, then &lt;code&gt;:wq&lt;/code&gt; to save the file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the file permissions to executable.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x transfer_script
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the executable.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./transfer_script
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Reference Links
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/virtual-machines/scripts/copy-snapshot-to-storage-account" rel="noopener noreferrer"&gt;Microsoft Official Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Whether you’re migrating a single snapshot or handling multiple backups across subscriptions, automating the process saves time and ensures accuracy. With the script provided, you can adapt it to your specific needs and scale operations as required.&lt;/p&gt;

&lt;p&gt;Reach out to me via &lt;a href="https://www.linkedin.com/in/angelotheman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; , &lt;a href="https://x.com/angelotheman" rel="noopener noreferrer"&gt;X&lt;/a&gt; and &lt;a href="//mailto:kwabenaatwumasi@gmail.com"&gt;Email&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cheers 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>azure</category>
      <category>tutorial</category>
      <category>bash</category>
    </item>
    <item>
      <title>Getting Started With Terraform For Infrastructure Provisioning 🛠️</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Wed, 19 Jun 2024 16:59:59 +0000</pubDate>
      <link>https://dev.to/angelotheman/getting-started-with-terraform-for-infrastructure-provisioning-15hi</link>
      <guid>https://dev.to/angelotheman/getting-started-with-terraform-for-infrastructure-provisioning-15hi</guid>
      <description>&lt;p&gt;Infrastructure as Code (IaC) is a modern approach to managing and provisioning computing resources through machine-readable configuration files rather than physical hardware or interactive configuration tools. This method allows for more consistent and scalable infrastructure management, enabling automation and reducing the risk of human error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Terraform?
&lt;/h3&gt;

&lt;p&gt;Terraform, developed by &lt;a href="https://www.hashicorp.com/" rel="noopener noreferrer"&gt;Hashicorp&lt;/a&gt; is one of the most popular IaC tools due to its open-source nature, flexibility, and support for multiple cloud platforms. It lets users define and provision data center infrastructure using a high-level configuration language.&lt;/p&gt;

&lt;p&gt;In this article, you will learn how to use Terraform as an IaC tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Basics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Terraform?
&lt;/h3&gt;

&lt;p&gt;Terraform is an open-source Infrastructure as Code (IaC) tool that allows you to define and provision infrastructure using a high-level configuration language called &lt;strong&gt;Hashicorp Configuration Language (HCL). *&lt;em&gt;Terraform manages resources such as virtual machines, storage, and networking for various cloud providers through a *&lt;/em&gt;&lt;em&gt;declarative approach&lt;/em&gt;&lt;/strong&gt;, where you simply define the desired state of your infrastructure and Terraform ensures that it matches that state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview of Architecture and Workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficzoijy7aexoy49wr30d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficzoijy7aexoy49wr30d.png" alt="Terraform Workflow" width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt;FIG 1.1&lt;/center&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgzumg4clh46feqpvzbt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgzumg4clh46feqpvzbt.png" alt="Terraform Architecture" width="341" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt;FIG 1.2&lt;/center&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A typical Terraform workflow as shown in &lt;strong&gt;&lt;em&gt;FIG 1.1&lt;/em&gt;&lt;/strong&gt; involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Writing configuration files to define the desired state.&lt;/li&gt;
&lt;li&gt;Initializing the configuration directory with &lt;code&gt;terraform init&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Creating an execution plan with &lt;code&gt;terraform plan&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Applying the changes with &lt;code&gt;terraform apply&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Managing the infrastructure state and making updates as needed.&lt;/li&gt;
&lt;li&gt;Destroying the infrastructure with &lt;code&gt;terraform destroy&lt;/code&gt; if required.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key Components
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Providers
&lt;/h4&gt;

&lt;p&gt;Providers are responsible for managing the lifecycle of resources. They offer a set of resources and data sources that Terraform can manage. Each provider requires a configuration to define the credentials and regions where Terraform would operate. Examples of providers include AWS, Azure, GCP, etc.&lt;/p&gt;

&lt;p&gt;Example configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Resources
&lt;/h4&gt;

&lt;p&gt;Resources are the fundamental building blocks of Terraform configurations. They represent components of your infrastructure, such as virtual machines, databases, or networking components. Each resource is defined with a type, name, and a set of properties.&lt;/p&gt;

&lt;p&gt;Example resource definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Modules
&lt;/h4&gt;

&lt;p&gt;Modules are reusable configurations that help organize and structure your code. They allow you to group multiple resources and encapsulate complex infrastructure patterns.&lt;/p&gt;

&lt;p&gt;Example module usage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform-aws-modules/vpc/aws"&lt;/span&gt;
  &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2.77.0"&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-vpc"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/16"&lt;/span&gt;
  &lt;span class="nx"&gt;azs&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1b"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;public_subnets&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"10.0.2.0/24"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;private_subnets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.3.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"10.0.4.0/24"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up your Environment
&lt;/h2&gt;

&lt;p&gt;Visit the &lt;a href="https://developer.hashicorp.com/terraform/install" rel="noopener noreferrer"&gt;Terraform downloads page&lt;/a&gt; and download or install the version of Terraform concerning your operating system.&lt;/p&gt;

&lt;p&gt;For Linux systems (Ubuntu/Debian) follow this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O-&lt;/span&gt; https://apt.releases.hashicorp.com/gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/hashicorp-archive-keyring.gpg

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/hashicorp.list

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;STEP 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verify the installation with this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Terraform –version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;STEP 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For this article, we will be provisioning our infrastructure using AWS.&lt;/p&gt;

&lt;p&gt;Use &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to install the &lt;strong&gt;&lt;em&gt;aws cli&lt;/em&gt;&lt;/strong&gt; for your operating system&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;aws configure&lt;/code&gt; to set your variables after installing the aws cli. Terraform needs to be able to use these credentials for infrastructure provisioning. &lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Your First Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basic Configuration File
&lt;/h3&gt;

&lt;p&gt;Terraform configuration files are written in Hashicorp Configuration Language (HCL). The basic structure as shown in **FIG 1.2 **above includes&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Provider Configuration:&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Specifies the cloud provider and its settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Resource Definition:&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Declares the resources to be managed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;resource:&lt;/em&gt;&lt;/strong&gt; This tells Terraform that this is a resource block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;aws_instance:&lt;/em&gt;&lt;/strong&gt; This is the actual resource we want to provision in aws.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;example:&lt;/em&gt;&lt;/strong&gt; This is a specific name given to the resource so that we can reference it elsewhere in our terraform code&lt;/p&gt;

&lt;h4&gt;
  
  
  Variables:
&lt;/h4&gt;

&lt;p&gt;Defines variables for dynamic values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ami_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"The name of the machine image (AMI) to use for the server."&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;ubuntu-local&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;variable:&lt;/em&gt;&lt;/strong&gt; This indicates a variable block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;ami_name:&lt;/em&gt;&lt;/strong&gt; This is the name of the variable. Hence, it can be referenced anywhere in the terraform code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;description:&lt;/em&gt;&lt;/strong&gt; The description should explain the variable and what value is expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;default:&lt;/em&gt;&lt;/strong&gt; If present, the variable is considered optional and the default value will be used if no value is set when calling the module or running Terraform.&lt;/p&gt;

&lt;h4&gt;
  
  
  Outputs:
&lt;/h4&gt;

&lt;p&gt;Specify outputs to display after applying the configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"instance_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Writing your first &lt;code&gt;main.tf&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;Create a directory for your terraform config files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;terraform-practise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the &lt;code&gt;main.tf&lt;/code&gt; file in this directory. This file would contain your Terraform configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we initialize the directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding the Initialization Process and Its Output
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Provider Plugins:&lt;/strong&gt; Terraform downloads the necessary provider plugins specified in your configuration. In our case aws.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend Initialization:&lt;/strong&gt; Terraform sets up the backend for storing the state of your infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Directory Structure:&lt;/strong&gt; Terraform creates a &lt;code&gt;.terraform&lt;/code&gt; directory to store the provider plugins and state files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A sample output would look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
Initializing the backend...

Initializing provider plugins...

- Finding latest version of hashicorp/aws...

- Installing hashicorp/aws v3.27.0...

- Installed hashicorp/aws v3.27.0 &lt;span class="o"&gt;(&lt;/span&gt;signed by HashiCorp&lt;span class="o"&gt;)&lt;/span&gt;

Terraform has been successfully initialized!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Terraform Commands
&lt;/h2&gt;

&lt;p&gt;To view the entire list of commands, do &lt;code&gt;terraform –help&lt;/code&gt;. Here are some commands and their uses&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/strong&gt;: Initializes a Terraform working directory by downloading the necessary provider plugins and setting up the backend for state management. This should be run first before any other terraform command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform fmt&lt;/code&gt;&lt;/strong&gt;: This command is used to ensure the configuration files are properly formatted and easy to read. It helps maintain a consistent style across the files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform validate&lt;/code&gt;&lt;/strong&gt;: Checks whether the configuration is valid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform plan&lt;/code&gt;&lt;/strong&gt;: This command is used to preview the changes that Terraform will make to the infrastructure. It helps in verifying the resources that will be created, modified, or destroyed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform apply&lt;/code&gt;&lt;/strong&gt;: This command executes the actions proposed in the execution plan. It prompts for approval before making any changes unless the &lt;code&gt;-auto-approve&lt;/code&gt; flag is used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform destroy&lt;/code&gt;&lt;/strong&gt;: This command is used to terminate and remove all resources defined in the Terraform configuration. It prompts for approval before making any changes unless the &lt;code&gt;-auto-approve&lt;/code&gt; flag is used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform show&lt;/code&gt;&lt;/strong&gt;: This command is used to inspect the current state of the infrastructure managed by Terraform. It can also show the details of a specific plan file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;terraform refresh&lt;/code&gt;&lt;/strong&gt;: This command reconciles the state file with the real-world resources to detect any drift between the two.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Example: Setting Up an EC2 Instance with a VPC
&lt;/h2&gt;

&lt;p&gt;In this example, we will provision an EC2 instance within a VPC. This configuration will include&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a VPC&lt;/li&gt;
&lt;li&gt;Subnets&lt;/li&gt;
&lt;li&gt;An internet gateway&lt;/li&gt;
&lt;li&gt;Route tables&lt;/li&gt;
&lt;li&gt;EC2 instance with appropriate security groups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this demonstration, we will create a new folder in our main directory named &lt;strong&gt;&lt;em&gt;learn-terraform-aws.&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;learn-terraform-aws

&lt;span class="nb"&gt;cd &lt;/span&gt;learn-terraform-aws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We would then create our &lt;code&gt;main.tf&lt;/code&gt; file responsible for holding our terraform configurations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;main.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we will define the VPC resource in the &lt;code&gt;main.tf&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/16"&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"main-vpc"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we define the public and private subnets within the VPC&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_subnet"&lt;/span&gt; &lt;span class="s2"&gt;"public"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.1.0/24"&lt;/span&gt;
  &lt;span class="nx"&gt;availability_zone&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1a"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"public-subnet"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_subnet"&lt;/span&gt; &lt;span class="s2"&gt;"private"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.2.0/24"&lt;/span&gt;
  &lt;span class="nx"&gt;availability_zone&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1a"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"private-subnet"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, we create our internet gateway to allow access to the VPC&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_internet_gateway"&lt;/span&gt; &lt;span class="s2"&gt;"gw"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"main-gateway"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define a route table and associate it with the public subnet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route_table"&lt;/span&gt; &lt;span class="s2"&gt;"public"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;
    &lt;span class="nx"&gt;gateway_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_internet_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"public-route-table"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route_table_association"&lt;/span&gt; &lt;span class="s2"&gt;"public"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_id&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;route_table_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_route_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we create our EC2 Instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"web"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_id&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"web-server"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would realize that we are simply declaring the state of our infrastructure like we would if we were to go to the AWS console. Also, The specific name of the resource blocks for our file is being reused as and when necessary. For instance, in the &lt;code&gt;aws_instance&lt;/code&gt; resource, we made use of &lt;code&gt;aws_subnet.public.id&lt;/code&gt; which is a named resource in our configuration telling terraform which resource to get this id from.&lt;/p&gt;

&lt;h3&gt;
  
  
  Variables and Outputs
&lt;/h3&gt;

&lt;p&gt;Add variables and outputs to make the configuration more flexible and provide useful information after the infrastructure is provisioned.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;variables.tf&lt;/code&gt; file and add this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"aws_region"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"The AWS region to deploy resources"&lt;/span&gt;

  &lt;span class="nx"&gt;default&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"instance_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Type of EC2 instance"&lt;/span&gt;

  &lt;span class="nx"&gt;default&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create an &lt;code&gt;outputs.tf&lt;/code&gt; file and add this code as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;
&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"instance_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;web&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"public_ip"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;web&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public_ip&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now ensure that all three files are in the same directory and run the following commands&lt;/p&gt;

&lt;p&gt;STEP 1. Initialize the directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;STEP 2. Create an Execution Plan&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;STEP 3. Apply the configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;STEP 4. After &lt;code&gt;terraform apply&lt;/code&gt; is complete, you will see the instance ID and public IP of the newly created EC2 instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.hashicorp.com/terraform/docs" rel="noopener noreferrer"&gt;Terraform Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/what-is/iac/" rel="noopener noreferrer"&gt;Infrastructure as Code (IaC)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we've explored the foundational aspects of using Terraform for infrastructure provisioning. From understanding the core concepts and basic commands to diving into practical scenarios like setting up an EC2 instance with a VPC, we've covered essential topics that will help you get started with Terraform.&lt;/p&gt;

&lt;p&gt;Reach out to me via &lt;a href="https://www.linkedin.com/in/angelotheman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; , &lt;a href="https://x.com/angelotheman" rel="noopener noreferrer"&gt;X&lt;/a&gt; via &lt;a href="//mailto:kwabenaatwumasi@gmail.com"&gt;Email&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy Learning 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>cloud</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Git Branching Strategies for DevOps: Best Practices for Collaboration</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Mon, 10 Jun 2024 11:12:42 +0000</pubDate>
      <link>https://dev.to/angelotheman/git-branching-strategies-for-devops-best-practices-for-collaboration-35l8</link>
      <guid>https://dev.to/angelotheman/git-branching-strategies-for-devops-best-practices-for-collaboration-35l8</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This article is intended for readers who are already familiar with GitHub and understand its functionality. If you’re new to GitHub, consider exploring some introductory resources &lt;strong&gt;&lt;a href="https://dev.to/angelotheman/master-git-commands-with-this-handy-cheat-sheet-4412"&gt;HERE&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Git Branching in DevOps
&lt;/h2&gt;

&lt;p&gt;In a fast-paced world of software engineering, efficient and effective code management is crucial. Git branching strategies play a vital role in maintaining a smooth workflow and ensuring seamless collaboration among team members.&lt;/p&gt;

&lt;p&gt;This article aims to explore various Git branching strategies, offering insights and best practices to help you and your team enhance your collaborative efforts and streamline your development process.&lt;/p&gt;

&lt;h1&gt;
  
  
  Understanding Git Branching
&lt;/h1&gt;

&lt;p&gt;In Git, a &lt;strong&gt;branch&lt;/strong&gt; represents a single line of development. Branches allow multiple developers to work on different features, bug fixes, or experiments simultaneously without interfering with the main codebase. This flexibility is crucial in the DevOps environment where continuous integration and continuous delivery practices demand frequent updates and deployments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Concepts:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Branches:&lt;/strong&gt; Parallel lines of development that diverge from the main project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commits:&lt;/strong&gt; Individual changes or updates made to the codebase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merges:&lt;/strong&gt; The process of integrating changes from one branch into another.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Git Branching Strategies
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Trunk-Based Development
&lt;/h2&gt;

&lt;p&gt;Trunk-based development focuses on having a single main branch, often referred to as the &lt;strong&gt;&lt;em&gt;"trunk"&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;em&gt;"main."&lt;/em&gt;&lt;/strong&gt; Developers commit to this branch frequently, ensuring that the codebase is always in a deployable state. If branches are used, they are short-lived and quickly merge back into the trunk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Simplifies the CI process&lt;/li&gt;
&lt;li&gt;Reduces complexity in managing branches&lt;/li&gt;
&lt;li&gt;Promotes rapid delivery and quick feedback cycles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Frequent integration can lead to conflicts&lt;/li&gt;
&lt;li&gt;Requires discipline in maintaining build and test stability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub Flow
&lt;/h2&gt;

&lt;p&gt;GitHub Flow is a simple and effective branching strategy that revolves around a single production-ready branch, typically named main or master. Development work is done on short-lived feature branches, and changes are merged into the main branch through pull requests, which facilitate collaboration and code review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keep the branching model simple&lt;/li&gt;
&lt;li&gt;Pull requests encourage collaboration and code reviews&lt;/li&gt;
&lt;li&gt;Integrates well with CI/CD pipelines for continuous deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can become difficult to manage large teams&lt;/li&gt;
&lt;li&gt;Relies on thorough code reviews to maintain quality&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Git Flow
&lt;/h2&gt;

&lt;p&gt;Git Flow uses multiple long-lived branches, including &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;develop&lt;/code&gt;, &lt;code&gt;release&lt;/code&gt;, and &lt;code&gt;hotfix&lt;/code&gt;, in addition to short-lived feature branches. This strategy provides a structured process for managing different types of changes, making it ideal for large teams and complex projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Organized and structured process&lt;/li&gt;
&lt;li&gt;Clear separation between production and development code&lt;/li&gt;
&lt;li&gt;Scales well for large teams and complex projects&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can be overly complex for smaller teams or projects&lt;/li&gt;
&lt;li&gt;Frequent merging and branch management can be time-consuming&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Feature Branching (Feature-Based Development)
&lt;/h2&gt;

&lt;p&gt;Feature Branching involves creating a dedicated branch for each feature, which may be long-lived or short-lived. This strategy allows multiple features to be developed in parallel without affecting the main branch. Features are merged back into the main branch once they are complete and tested&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Each feature is isolated, reducing the risk of conflicts&lt;/li&gt;
&lt;li&gt;Facilitates parallel development&lt;/li&gt;
&lt;li&gt;Maintains a clear commit history for each feature&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Features might stay in separate branches for too long, leading to integration challenges&lt;/li&gt;
&lt;li&gt;Merging multiple feature branches can be complex and error-prone&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;h4&gt;Strategy&lt;/h4&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;h4&gt;Key Feature&lt;/h4&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;h4&gt;Main Advantage&lt;/h4&gt;
  &lt;/td&gt;
   &lt;td&gt;
&lt;h4&gt;Main Disadvantage&lt;/h4&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Trunk-Based&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Single main branch
   &lt;/td&gt;
   &lt;td&gt;Simplifies CI and rapid delivery
   &lt;/td&gt;
   &lt;td&gt;Frequent integration conflicts
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;GitHub Flow&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Feature branches + PRs
   &lt;/td&gt;
   &lt;td&gt;Encourages collaboration and code reviews
   &lt;/td&gt;
   &lt;td&gt;Not ideal for large teams
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Git Flow&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Multiple long-lived branches
   &lt;/td&gt;
   &lt;td&gt;Structured process, clear separation
   &lt;/td&gt;
   &lt;td&gt;Can be complex and time-consuming
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Feature Branching&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Dedicated feature branches
   &lt;/td&gt;
   &lt;td&gt;Isolation and parallel development
   &lt;/td&gt;
   &lt;td&gt;Integration delays and complex merges
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here is a sample code snippet that summarizes creation and merging of branches&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create and switch to a develop branch&lt;/span&gt;

git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; develop

&lt;span class="c"&gt;# Create a feature branch from develop&lt;/span&gt;

git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature-branch develop

&lt;span class="c"&gt;# Make changes and commit&lt;/span&gt;

git add &lt;span class="nb"&gt;.&lt;/span&gt;

git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Implement new feature"&lt;/span&gt;

&lt;span class="c"&gt;# Merge feature branch back to develop&lt;/span&gt;

git checkout develop

git merge feature-branch

&lt;span class="c"&gt;# When ready for release, merge develop to master&lt;/span&gt;

git checkout master

git merge develop

&lt;span class="c"&gt;# Tag the release&lt;/span&gt;

git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v1.0 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Release version 1.0"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Choosing the Right Strategy
&lt;/h1&gt;

&lt;p&gt;Selecting the appropriate branching strategy depends on several factors, including team size and deployment frequency. Let’s take a closer look at how these factors influence the choice of branching strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Team Size
&lt;/h2&gt;

&lt;p&gt;The size of your development team significantly impacts the choice of branching strategy. Smaller teams often benefit from simpler and more streamlined approaches whereas larger teams may require more structured strategies to manage their workflows effectively. Below is a table outlining recommended branching strategies based on team size.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;h4&gt;Team Size&lt;/h4&gt;


   &lt;/td&gt;
   &lt;td&gt;
&lt;h4&gt;Recommended Strategies&lt;/h4&gt;


   &lt;/td&gt;
   &lt;td&gt;
&lt;h4&gt;Reasoning&lt;/h4&gt;


   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Small team (1 - 5 members)&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Trunk Based development, GitHub Flow
   &lt;/td&gt;
   &lt;td&gt;Simpler strategies minimize overhead and facilitate rapid integration.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Medium team (6 - 20 members)&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Github Flow, Feature Branching
   &lt;/td&gt;
   &lt;td&gt;Structured branching to handle multiple features and tasks simultaneously.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Large team (20+)&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Feature Branching, Git Flow
   &lt;/td&gt;
   &lt;td&gt;A structured approach to managing multiple parallel developments and releases.
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Deployment Frequency
&lt;/h2&gt;

&lt;p&gt;The frequency with which your team deploys code is another critical factor in selecting the right branching strategy. High deployment frequency necessitates approaches that support rapid integration and deployment, while less frequent deployments can accommodate more complex and structured branching models. The table below summarizes the recommended strategies based on deployment frequency.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;h4&gt;Deployment Frequency&lt;/h4&gt;


   &lt;/td&gt;
   &lt;td&gt;
&lt;h4&gt;Recommended Strategies&lt;/h4&gt;


   &lt;/td&gt;
   &lt;td&gt;
&lt;h4&gt;Reasoning&lt;/h4&gt;


   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;High Frequency&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Trunk Based Development, GitHub Flow
   &lt;/td&gt;
   &lt;td&gt;Supports continuous integration and quick deployments.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Moderate Frequency&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;GitHub Flow, Feature Branching
   &lt;/td&gt;
   &lt;td&gt;Balances structure and flexibility for regular updates.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Low Frequency&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;Feature Branching, Git Flow
   &lt;/td&gt;
   &lt;td&gt;Manages long development cycles and ensures stability.
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Best Practices For Collaboration
&lt;/h1&gt;

&lt;p&gt;Effective collaboration is essential for the success of any development team, regardless of the chosen branching strategy. Here are some best strategies to ensure smooth collaboration and maximize productivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Effective Communication
&lt;/h2&gt;

&lt;p&gt;Clear and consistent communication is crucial for avoiding misunderstandings and ensuring everyone is on the same page. Some ways to enhance communication within your team are as follows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hold daily stand-ups or weekly check-ins to discuss progress, challenges, and next steps&lt;/li&gt;
&lt;li&gt;Leverage communication tools like Slack, Microsoft Teams, or Discord for real-time communication and updates.&lt;/li&gt;
&lt;li&gt;Maintain comprehensive documentation of processes, guidelines, and project details. Tools like Confluence or Notion can help with that&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Reviews and Pull Requests
&lt;/h2&gt;

&lt;p&gt;Code reviews are vital for maintaining code quality and knowledge sharing within the team. Best practices for conducting code reviews are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define clear guidelines for code reviews, including what to look for, and provide constructive feedback.&lt;/li&gt;
&lt;li&gt;Use automated tools to check for code quality, style, and security issues before the review process. I covered that in my previous article &lt;strong&gt;&lt;a href="https://dev.to/angelotheman/how-to-set-up-github-actions-for-continuous-integration-2054"&gt;HERE&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Encourage developers to create small, focused pull requests that are easier to review and merge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Handling Conflicts and Merges
&lt;/h2&gt;

&lt;p&gt;Merge conflicts are inevitable in collaborative development, but they can be managed effectively with the right approach. Here’s how to handle conflicts and merges smoothly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regularly merge changes from the main branch into feature branches to minimize conflicts. This keeps your branch up-to-date with the latest changes.&lt;/li&gt;
&lt;li&gt;Address conflicts as soon as they arise to prevent them from becoming more complex over time.&lt;/li&gt;
&lt;li&gt;Involve team members in resolving conflicts, especially if the changes affect multiple areas of the codebase. Pair programming or mob programming can be useful for resolving tricky conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Integrating with CI/CD
&lt;/h2&gt;

&lt;p&gt;Aligning your branching strategy with continuous integration and continuous delivery practices is essential for efficient development and deployment. Here’s how to integrate your branching strategy with CI/CD:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up automated builds and tests for each branch to catch issues early. Tools like Jenkins, Travis CI, and GitHub Actions can help.&lt;/li&gt;
&lt;li&gt;Configure your CI/CD pipeline to deploy changes automatically from the main branch or a designated release branch. This ensures that your code is always in a deployable state.&lt;/li&gt;
&lt;li&gt;Use feature flags to deploy incomplete features safely. This allows you to release code to production while keeping new features hidden until they are ready.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Helpful links
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gitkraken.com/learn/git/best-practices/git-branch-strategy"&gt;Git Branch Strategy - GitKraken&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging"&gt;Git Branching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/agile/software-development/branching"&gt;Branching Strategies - Atlassian&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In the fast-paced world of software development, choosing the right Git branching strategy is crucial for maintaining efficiency and collaboration within your team. By understanding the needs of your team size and deployment frequency, you can select a strategy that balances simplicity and structure, ensuring smooth development workflows.&lt;/p&gt;

&lt;p&gt;I believe this article has saved you a ton of time in integrating and deciding which branching strategies to use.&lt;/p&gt;

&lt;p&gt;Don't forget to connect with me on &lt;strong&gt;&lt;a href="https://linkedin.com/in/angelotheman"&gt;LinkedIn&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://x.com/_angelotheman"&gt;X&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Happy Learning 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorial</category>
      <category>git</category>
      <category>development</category>
    </item>
    <item>
      <title>How to Set Up GitHub Actions for Continuous Integration</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Thu, 23 May 2024 13:20:37 +0000</pubDate>
      <link>https://dev.to/angelotheman/how-to-set-up-github-actions-for-continuous-integration-2054</link>
      <guid>https://dev.to/angelotheman/how-to-set-up-github-actions-for-continuous-integration-2054</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the fast-paced world of software development, ensuring that code is consistently tested and integrated can be a challenging task. This is where &lt;strong&gt;Continuous Integration (CI)&lt;/strong&gt; comes to play.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CI is a development practice that requires developers to integrate code into a shared repository frequently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;CI automates the process of building, testing and integrating code changes regularly, helping developers to catch issues early and maintain a stable codebase.&lt;/p&gt;

&lt;p&gt;GitHub Actions, a powerful feature introduced by GitHub, has revolutionized the way developers automate their workflows. We will explore how to use this tool for setting up CI in your projects.&lt;/p&gt;

&lt;p&gt;Here's what we will cover&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding CI and it's benefits&lt;/li&gt;
&lt;li&gt;Introduction to GitHub Actions&lt;/li&gt;
&lt;li&gt;Building CI workflows with Github Actions&lt;/li&gt;
&lt;li&gt;Advanced Techniques and Integration with External Tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits of Continuous Integration
&lt;/h2&gt;

&lt;p&gt;There are several benefits to Continuous Integration. These include&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early Detection of Bugs&lt;/strong&gt;&lt;br&gt;
Continuous Integration facilitates the early detection of bugs by automatically running tests with each code integration, allowing developers to identify and fix issues before they escalate, resulting in more stable software releases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved Code Quality&lt;/strong&gt;&lt;br&gt;
By ensuring consistent coding standards and practices through automated testing and integration, code quality is checked. This reduces technical debt and ensures the maintainability of the codebase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Faster Feedback Loop&lt;/strong&gt;&lt;br&gt;
With Continuous Integration, developers receive rapid feedback on their code, enabling them to iterate quickly and address issues promptly leading to faster development cycles.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are some of the benefits derived from Continuous Integration. Now let's look at using GitHub actions for CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to GitHub Actions
&lt;/h2&gt;

&lt;p&gt;GitHub Actions serves as a platform for continuous integration and continuous delivery (CI/CD), enabling you to automate the process of building, testing, and deploying your software pipeline. &lt;/p&gt;

&lt;p&gt;Here are some uses of GitHub Actions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can set up workflows that automatically build and test each pull request submitted to your repository.&lt;/li&gt;
&lt;li&gt;Deploy successfully merged pull requests to your production environment.&lt;/li&gt;
&lt;li&gt;Actions can also be used to package or release projects into the pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub Actions goes beyond just DevOps and lets you run workflows when other events happen in your repository. For example, you can run a workflow to automatically add the appropriate labels whenever someone creates a new issue in your repository. It has gained popularity for its simplicity and the fact that it is integrated directory into your repository.&lt;/p&gt;

&lt;p&gt;Now let's look at the components that make up a GitHub workflow&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding a Github Action Workflow
&lt;/h2&gt;

&lt;p&gt;A workflow is a configurable automated process that will run one or more jobs. A GitHub Actions workflow is defined by a YAML file typically located in the &lt;code&gt;.github/workflows&lt;/code&gt; directory within your repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Components of a workflow
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Triggers&lt;/strong&gt;&lt;br&gt;
These define the event that trigger the workflow. Example, the workflow can start when a user:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a pull request&lt;/li&gt;
&lt;li&gt;Opens an issue&lt;/li&gt;
&lt;li&gt;Pushes a commit to the repository
etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Jobs&lt;/strong&gt;&lt;br&gt;
These specify the individual tasks to be executed as part of the workflow. Each job runs sequentially or in parallel and can include multiple steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;br&gt;
Define the individual actions or commands to be executed within a job. Steps can include tasks like checking out code, running tests, or deploying artifacts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actions&lt;/strong&gt;&lt;br&gt;
Actions are reusable units of code that perform specific tasks within a workflow. They can be authored by GitHub or by the community and can be easily integrated into workflows. An action can pull your git repository from GitHub, set up the correct toolchain for your build environment&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Runners&lt;/strong&gt;&lt;br&gt;
A runner is a server that runs your workflows when they're triggered. Each runner can run a single job at a time. GitHub provides three runners to run your workflows: &lt;em&gt;Ubuntu Linux&lt;/em&gt;, &lt;em&gt;Microsoft Windows&lt;/em&gt; and &lt;em&gt;macOS&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build an example workflow
&lt;/h2&gt;

&lt;p&gt;In this section we would set up a simple workflow that &lt;strong&gt;&lt;em&gt;runs linters&lt;/em&gt;&lt;/strong&gt; for Python using pycodestyle. This will help ensure that your Python code adheres to PEP 8 style guidelines and is free of common errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-By-Step Guide
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create the &lt;code&gt;.github/workflows&lt;/code&gt; directory at the root of your repository.&lt;/li&gt;
&lt;li&gt;Inside the directory, create a file &lt;code&gt;lint.yml&lt;/code&gt;. Go to &lt;strong&gt;Add file&lt;/strong&gt; and then write the directory as shown in the image below&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni2vrd64wmtsf7i8dcjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni2vrd64wmtsf7i8dcjx.png" alt="Creating the directory and the file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, commit the changes for it to take effect.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;code&gt;lint.yml&lt;/code&gt; file and add the following code&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint Python Code&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Python&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v4&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.x'&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Pycodestyle&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pip install pycodestyle&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint Python files with Pycodestyle&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pycodestyle .&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Explanation of the code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: Defines the name of the workflow as "Lint Python Code".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;on&lt;/code&gt;: Triggers the workflow on push or pull request events to the main branch. Hence, anytime there's a pull request to merge code or pushing to main branch, this workflow would be triggered.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jobs&lt;/code&gt;: Defines a single job named &lt;strong&gt;&lt;em&gt;lint&lt;/em&gt;&lt;/strong&gt; that executes the linting steps.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;runs-on&lt;/code&gt;: Specifies the environment which would run the workflow, in our case, &lt;code&gt;ubuntu-latest&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;steps&lt;/code&gt;: This section defines the sequential steps within the job:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Checkout Code&lt;/code&gt;: Uses the &lt;em&gt;actions/checkout&lt;/em&gt; action to check 
out the repository code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Set up Python&lt;/code&gt;: Uses the actions/setup-python action to set up 
a Python environment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Install Pycodestyle&lt;/code&gt;: Installs the Pycodestyle linter for 
Python files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Lint Python Files&lt;/code&gt;: Runs Pycodestyle on the entire repository 
to check for PEP 8 compliance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This workflow ensures that every time code is pushed or a pull request is created, Pycodestyle is automatically run to check for style issues in Python code.&lt;/p&gt;

&lt;p&gt;Now let's create a simple python file &lt;code&gt;hello.py&lt;/code&gt; in our repository with the following code&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="c1"&gt;#!/usr/bin/python3
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
This is a function file
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now commit and push this code to your repository. The workflow would automatically be triggered since we specified a &lt;strong&gt;push&lt;/strong&gt; in the trigger. You would see something equivalent to the image below in the actions tab&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmiywqfvj2kznszrnlc5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmiywqfvj2kznszrnlc5o.png" alt="Full set of job hisory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when there's an error in the workflow (which normally reflects an error in the codebase), it would be marked &lt;strong&gt;red&lt;/strong&gt; otherwise, it would check and you'll get something like the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh177vcgk0407wfahitg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh177vcgk0407wfahitg.png" alt="Checked Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging a workflow
&lt;/h2&gt;

&lt;p&gt;Here's another python code which should fail in the workflow. We would then learn how to debug or troubleshoot a workflow.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="c1"&gt;#!/usr/bin/python3
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
This is a function file
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This is me&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is what we get from the workflow&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filmbgvfz2q9z4gbgp8c8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filmbgvfz2q9z4gbgp8c8.png" alt="History of workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click on the failed workflow to troubleshoot&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3e2088u0jej2g3lts1n8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3e2088u0jej2g3lts1n8.png" alt="Description of failed workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The logs rightly shows what needs to be done to get the linter to check correctly.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

./python_with_error.py:6:1: E302 expected 2 blank lines, found 1
./python_with_error.py:9:1: E302 expected 2 blank lines, found 1
./python_with_error.py:10:3: E111 indentation is not a multiple of 4
./python_with_error.py:12:1: E305 expected 2 blank lines after class or function definition, found 1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As shown above, there needs to be blank lines added and indentation issues. This gives you a sense of what exactly didn't allow the code to flow in the pipeline. &lt;/p&gt;

&lt;p&gt;After fixing the issues with pycodestyle, you should have the equivalent of these&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frp21txruxziegrbwky3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frp21txruxziegrbwky3i.png" alt="Fixed Issue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8h2xb415eatn6nh17v4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8h2xb415eatn6nh17v4o.png" alt="Checked issue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced CI Workflow Techniques
&lt;/h2&gt;

&lt;p&gt;There are other useful configurations when building a workflow. Let's look at three of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Variables
&lt;/h3&gt;

&lt;p&gt;Variables store non-sensitive information that can change depending on the environment or the context of the workflow.&lt;/p&gt;

&lt;p&gt;To add a new variable, navigate to &lt;strong&gt;Settings &amp;gt; Secrets and Variables &amp;gt; Actions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpel98kb2mvyxj078v3z7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpel98kb2mvyxj078v3z7.png" alt="Variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z0nw5w6dfwv02zhwnhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z0nw5w6dfwv02zhwnhv.png" alt="Add Variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting environment-specific configurations, such as the target 
environment (development, staging, production).&lt;/li&gt;
&lt;li&gt;Storing file paths or URLs that might differ between environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Secrets
&lt;/h3&gt;

&lt;p&gt;Secrets store sensitive information securely, such as API keys, passwords, and tokens. They ensure that this information is not exposed in the workflow configuration or logs.&lt;/p&gt;

&lt;p&gt;To add a new secret, navigate to &lt;strong&gt;Settings &amp;gt; Secrets and Variables &amp;gt; Actions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpuz99s6wh83xe17m1y7k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpuz99s6wh83xe17m1y7k.png" alt="Secrets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfd2hbe74bogx46edqcq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfd2hbe74bogx46edqcq.png" alt="Add Secrets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stores access tokens for third-party services like AWS, Docker Hub, 
or email services.&lt;/li&gt;
&lt;li&gt;Database passwords or credentials for accessing secure services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Webhooks
&lt;/h3&gt;

&lt;p&gt;Webhooks trigger actions in response to specific events, such as sending notifications to external services.&lt;/p&gt;

&lt;p&gt;To add a new webhook, navigate to &lt;strong&gt;Settings &amp;gt; Webhooks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqg46shobva4kuy8symz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqg46shobva4kuy8symz.png" alt="Webhooks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq5hhh45fgnqmhut9tyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq5hhh45fgnqmhut9tyw.png" alt="Add Webhook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sending notifications to Slack, email, or SMS services when a build 
fails or succeeds.&lt;/li&gt;
&lt;li&gt;Initiating deployments to environments such as staging or production 
when certain conditions are met.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's add a notification to our workflow such that, a SMS is automatically sent to us when our pipeline fails.&lt;/p&gt;

&lt;p&gt;Edit the &lt;code&gt;yml&lt;/code&gt; file with the following code snippet&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI Pipeline&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;br&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;br&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="na"&amp;gt;steps&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt;
&amp;lt;span class="pi"&amp;gt;-&amp;lt;/span&amp;gt; &amp;lt;span class="na"&amp;gt;name&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;Checkout code&amp;lt;/span&amp;gt;
  &amp;lt;span class="na"&amp;gt;uses&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;actions/checkout@v3&amp;lt;/span&amp;gt;

&amp;lt;span class="pi"&amp;gt;-&amp;lt;/span&amp;gt; &amp;lt;span class="na"&amp;gt;name&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;Set up Python&amp;lt;/span&amp;gt;
  &amp;lt;span class="na"&amp;gt;uses&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;actions/setup-python@v4&amp;lt;/span&amp;gt;
  &amp;lt;span class="na"&amp;gt;with&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt;
    &amp;lt;span class="na"&amp;gt;python-version&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s1"&amp;gt;'&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;3.x'&amp;lt;/span&amp;gt;

&amp;lt;span class="pi"&amp;gt;-&amp;lt;/span&amp;gt; &amp;lt;span class="na"&amp;gt;name&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;Install dependencies&amp;lt;/span&amp;gt;
  &amp;lt;span class="na"&amp;gt;run&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="pi"&amp;gt;|&amp;lt;/span&amp;gt;
    &amp;lt;span class="s"&amp;gt;pip install requests pycodestyle&amp;lt;/span&amp;gt;

&amp;lt;span class="pi"&amp;gt;-&amp;lt;/span&amp;gt; &amp;lt;span class="na"&amp;gt;name&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;Lint Python files with Pycodestyle&amp;lt;/span&amp;gt;
  &amp;lt;span class="na"&amp;gt;run&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="pi"&amp;gt;|&amp;lt;/span&amp;gt;
    &amp;lt;span class="s"&amp;gt;pycodestyle .&amp;lt;/span&amp;gt;

&amp;lt;span class="pi"&amp;gt;-&amp;lt;/span&amp;gt; &amp;lt;span class="na"&amp;gt;name&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;Send SMS Notification&amp;lt;/span&amp;gt;
  &amp;lt;span class="na"&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;failure()&amp;lt;/span&amp;gt;
  &amp;lt;span class="na"&amp;gt;run&amp;lt;/span&amp;gt;&amp;lt;span class="pi"&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;span class="pi"&amp;gt;|&amp;lt;/span&amp;gt;
    &amp;lt;span class="s"&amp;gt;python - &amp;amp;lt;&amp;amp;lt;EOF&amp;lt;/span&amp;gt;

    &amp;lt;span class="s"&amp;gt;import requests&amp;lt;/span&amp;gt;
    &amp;lt;span class="s"&amp;gt;import json&amp;lt;/span&amp;gt;

    &amp;lt;span class="s"&amp;gt;quicksend_url = "https://uellosend.com/quicksend/"&amp;lt;/span&amp;gt;

    &amp;lt;span class="s"&amp;gt;data = {&amp;lt;/span&amp;gt;
        &amp;lt;span class="s"&amp;gt;'api_key': '${{ secrets.SMS_API_KEY }}',&amp;lt;/span&amp;gt;
        &amp;lt;span class="s"&amp;gt;'sender_id': 'GitHub',&amp;lt;/span&amp;gt;
        &amp;lt;span class="s"&amp;gt;'message': 'CI Pipeline has failed, check the details',&amp;lt;/span&amp;gt;
        &amp;lt;span class="s"&amp;gt;'recipient': '${{ secrets.SMS_RECIPIENT }}'&amp;lt;/span&amp;gt;
    &amp;lt;span class="s"&amp;gt;}&amp;lt;/span&amp;gt;

    &amp;lt;span class="s"&amp;gt;headers = {'Content-type': 'application/json'}&amp;lt;/span&amp;gt;

    &amp;lt;span class="s"&amp;gt;response = requests.post(quicksend_url, headers=headers, json=data)&amp;lt;/span&amp;gt;

    &amp;lt;span class="s"&amp;gt;with open('sms_response.json', 'w') as f:&amp;lt;/span&amp;gt;
        &amp;lt;span class="s"&amp;gt;json.dump(response.json(), f, indent=4)&amp;lt;/span&amp;gt;
    &amp;lt;span class="s"&amp;gt;EOF&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Explanation of Code&lt;br&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We check for a failure of the task to be run then we send aSMS to the user.&lt;/li&gt;
&lt;li&gt;We use &lt;a href="https://uellosend.com/index.php" rel="noopener noreferrer"&gt;UelloSend&lt;/a&gt; for the SMS service.&lt;/li&gt;
&lt;li&gt;Secrets are configured for the services in the secrets file within the repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the SMS that would be sent should the run or job fail&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cu3e5amjqk5977szia2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cu3e5amjqk5977szia2.jpg" alt="Image of the error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/continuous-delivery/continuous-integration" rel="noopener noreferrer"&gt;Learn Continuous Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/learn-github-actions" rel="noopener noreferrer"&gt;Learn more about GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://uellosend.com/developer.php" rel="noopener noreferrer"&gt;UelloSend API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we explored how GitHub Actions can streamline and enhance your Continuous Integration (CI) workflows. By leveraging GitHub Actions, you can automate various aspects of your development process, ensuring code quality and improving collaboration among team members. &lt;/p&gt;

&lt;p&gt;By implementing these techniques, you can create robust CI workflows that not only automate code checks and tests but also keep you informed about the status of your builds in real-time. This enhances the overall development process, making it more efficient and reliable.&lt;/p&gt;

&lt;p&gt;What did you think? Share your thoughts and feedback in the comments below!&lt;/p&gt;

&lt;p&gt;Your input helps me deliver insightful and informative content in the future. Let's keep the conversation going!&lt;/p&gt;

&lt;p&gt;Connect with me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/angelotheman" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/_angelotheman" rel="noopener noreferrer"&gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linkedin.com/in/angelotheman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy learning 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorial</category>
      <category>github</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What happens when you type google.com in your browser and press Enter ❓</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Fri, 26 Apr 2024 12:55:14 +0000</pubDate>
      <link>https://dev.to/angelotheman/what-happens-when-you-type-googlecom-in-your-browser-and-press-enter-1p86</link>
      <guid>https://dev.to/angelotheman/what-happens-when-you-type-googlecom-in-your-browser-and-press-enter-1p86</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever wondered what exactly happens when you type &lt;em&gt;&lt;a href="http://www.google.com" rel="noopener noreferrer"&gt;www.google.com&lt;/a&gt;&lt;/em&gt; in your web browser? Of course, depending on your internet connection, you'd receive the &lt;a href="//htttps://www.google.com"&gt;google homepage&lt;/a&gt; homepage in a matter of micro-seconds.&lt;/p&gt;

&lt;p&gt;Did you know that there are lots of communications, channels and protocols which are ticked before the webpage is displayed on your screen? &lt;/p&gt;

&lt;p&gt;In this article, we would demystify the basics of everything which happens behind that scenes when you type any website into your web browser. We would go over some of the architecture, protocols and services responsible for serving us the pages we request for.&lt;/p&gt;

&lt;p&gt;Here is a simplified diagram showing most of the components we would talk about in this article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7ijharicvwmaw2521hj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7ijharicvwmaw2521hj.png" alt="Image of a web application architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS Resolution 🔍
&lt;/h2&gt;

&lt;p&gt;When you enter the Uniform Resource Locator (URL), &lt;em&gt;&lt;a href="http://www.google.com" rel="noopener noreferrer"&gt;www.google.com&lt;/a&gt;&lt;/em&gt;, DNS resolution is the first step in loading the webpage.&lt;/p&gt;

&lt;p&gt;DNS is like the phonebook of the internet. Instead of remembering IP addresses like 192.168.1.1, you can use domain names like &lt;em&gt;google.com&lt;/em&gt; to navigate the web. DNS translates human-readable domain names into IP addresses that computers use to identify each other on a network.&lt;/p&gt;

&lt;h3&gt;
  
  
  How DNS works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Local DNS Cache&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Your operating system typically has local DNS cache that stores recently accessed domain names and their corresponding IP address. If you've visited Google recently, your computer might already have this information cached, speeding up the process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;DNS Query&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
If the domain information is not cached locally, your computer sends a DNS query to a DNS resolver. The resolver is usually provided by your Internet Service Provider (ISP) or a third party service like Google DNS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Root Servers&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The resolver starts by querying the root servers to find the authoritative name server for the &lt;strong&gt;.com&lt;/strong&gt; top-level domain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Top-Level Domain (TLD) Servers&lt;/strong&gt;&lt;br&gt;
Once the resolver gets the information about the &lt;strong&gt;.com&lt;/strong&gt; TLD Server, it queries that server to find out the authoritative name server for &lt;strong&gt;&lt;em&gt;google.com&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authoritative Name Server&lt;/strong&gt;&lt;br&gt;
Finally the resolver queries the authoritative name server for &lt;strong&gt;&lt;em&gt;google.com&lt;/em&gt;&lt;/strong&gt; which provides the IP address associated with &lt;strong&gt;&lt;em&gt;google.com&lt;/em&gt;&lt;/strong&gt; and then returns it to your computer, allowing it to access the site&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  TCP/IP 🌐
&lt;/h2&gt;

&lt;p&gt;Once the IP address for &lt;strong&gt;&lt;em&gt;google.com&lt;/em&gt;&lt;/strong&gt; is found, TCP/IP takes over to establish connections between your computer and the google webserver.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transmission Control Protocol/ Internet Protocol (TCP/IP) is a set of rules for internet communication, ensuring that data get's to where it needs to go.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How TCP/IP Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Three Way Handshake&lt;/em&gt;&lt;/strong&gt;
Your computer and the server exchange synchronization (SYN) and acknowledgement (ACK) packets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Data Transfer&lt;/em&gt;&lt;/strong&gt;
Data is then sent in small packets over the established connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Connection Termination&lt;/em&gt;&lt;/strong&gt;
After the transfer of data the connection is closed&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Firewall 🛡️
&lt;/h2&gt;

&lt;p&gt;A firewall is a security system that monitors and controls incoming and outgoing network traffic based on a set of predetermined security rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  How a firewall works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A firewall inspects incoming and outgoing data packets to determine if they meet the security criteria set by the rules&lt;/li&gt;
&lt;li&gt;Based on those predefined rules, a firewall either allows or blocks the data packets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Firewalls essentially acts as a protective barrier between your computer and the internet, ensuring that only safe and authorized traffic can pass through.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTPS/SSL 🔐
&lt;/h2&gt;

&lt;p&gt;Once the firewall allows the connection, that connection has got to be secured using Https/SSL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;HTTPS (Hyper Text Transfer Protocol) is the secured version of HTTP and SSL (Secured Socket Layer) is the technology that encrypts the data transmitted between your browser and the webserver.&lt;br&gt;
&lt;a href="https://www.techtarget.com/searchsecurity/definition/Secure-Sockets-Layer-SSL" rel="noopener noreferrer"&gt;Learn about SSL&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.techtarget.com/searchsoftwarequality/definition/HTTPS" rel="noopener noreferrer"&gt;Learn about HTTPS&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How HTTPS/SSL operates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Encryption&lt;/em&gt;&lt;/strong&gt;
SSL encrypts the data transferred between your browser and the webserver, making it unreadable for anyone who intercepts the network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Authentication&lt;/em&gt;&lt;/strong&gt;
SSL certificates verify the identity of a website ensuring that you are connecting to the legitimate server and not a malicious one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Data Integrity&lt;/em&gt;&lt;/strong&gt;
SSL provides data integrity checks to ensure that data hasn't been altered during transmission.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Load Balancer ⚖️
&lt;/h2&gt;

&lt;p&gt;Google has various webservers which process different requests from client computers like yours. As such a load balancer is used to distribute the network traffic across those servers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A load balancer is a device or software that distributes incoming network traffic across multiple servers to ensure efficient use of resources, maximize throughput, and minimize response time.&lt;br&gt;
&lt;a href="https://www.techtarget.com/searchnetworking/definition/load-balancing" rel="noopener noreferrer"&gt;Read about load balancers&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How a load balancer works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A load balancer receives incoming requests and distributes them across multiple servers based on predefined algorithms such as round Robbin.&lt;/li&gt;
&lt;li&gt;Load balancers also monitor the health of servers by sending regular requests to check their status. If a server becomes unavailable or unhealthy, the load balancer redirects the traffic to another server.&lt;/li&gt;
&lt;li&gt;Load balancers can drop and add servers depending on the demand allowing for easy scalability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Webserver 🖥️
&lt;/h2&gt;

&lt;p&gt;After being directed by the load balancer, the request reaches the web server which hosts the website files.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A webserver is a software that serves web pages to clients over the internet using HTTP Protocol&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server" rel="noopener noreferrer"&gt;Read about Web server&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How the Web server works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When a request arrives from the client, the web server processes it, retrieves the requested files, and generates a response.&lt;/li&gt;
&lt;li&gt;The web server delivers the requested web pages, images or other resources to the client's web browser.&lt;/li&gt;
&lt;li&gt;In addition to serving static files, web servers can also execute scripts or interact with databases to generate dynamic content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples of the popular webservers include Nginx, Apache and Microsoft IIS&lt;/p&gt;

&lt;h2&gt;
  
  
  Application Server 📡
&lt;/h2&gt;

&lt;p&gt;The application server basically handles all dynamic content and business logic that the request contains.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Application Server is software that provides the runtime environment for web applications, allowing them to run and execute code written in programming languages.&lt;br&gt;
&lt;a href="https://www.serverwatch.com/guides/application-server/#:~:text=In%20a%20world%20where%20we%20rely%20on%20a,application%20data%20and%20web%20servers%20communicating%20with%20clients." rel="noopener noreferrer"&gt;Read about Application Server&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How the Application Server works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The application server executes the scripts to generate dynamic content based on user input, database queries or other factors.&lt;/li&gt;
&lt;li&gt;It often integrates with databases or other backend systems to fetch data to be returned to the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE&lt;/em&gt;&lt;/strong&gt;: Web servers is more fitted for static content, while the application server handles dynamic content.&lt;br&gt;
Read more about the differences &lt;a href="https://www.geeksforgeeks.org/difference-between-web-server-and-application-server/" rel="noopener noreferrer"&gt;HERE&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Database 🗃️
&lt;/h2&gt;

&lt;p&gt;After the application server handles dynamic content, it may interact with the database to retrieve or store information required for the web application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A database is a structured collection of data organized for efficient retrieval, storage, and management. It stores information such as user profiles, product details, or any other data needed by the web application.&lt;br&gt;
&lt;a href="https://www.oracle.com/database/what-is-database/" rel="noopener noreferrer"&gt;Read about databases&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How the database works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The database stores data in tables, with each table containing rows and columns representing individual records and fields, respectively.&lt;/li&gt;
&lt;li&gt;The application server sends queries to the database to retrieves or manipulate data. These queries are written using a query language like SQL.&lt;/li&gt;
&lt;li&gt;The database processes queries, retrieves the requested data and performs the necessary operations like filtering, sorting or aggregating.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In addition to the major routes and services discussed in this article, there are other microservices like CDNs (Content Delivery Networks) that also play a crucial role in delivering web content. While we've covered the essential components involved in the process of accessing a website like &lt;strong&gt;&lt;em&gt;google.com&lt;/em&gt;&lt;/strong&gt;, it is important to recognize the complexity of the underlying infrastructure that ensures the seamless delivery of content to your web browser.&lt;/p&gt;

&lt;p&gt;I invite you to share your thoughts and feedback in the comments section. Did this article meet your expectations?&lt;br&gt;
Your input is valuable in shaping future discussions and ensuring that we continue to provide insightful and informative content.&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://www.github.com/angelotheman" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, let's get interactive on &lt;a href="https://www.twitter.com/_angelotheman" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and form great connections on &lt;a href="https://www.linkedin.com/in/angelotheman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; 😊&lt;/p&gt;

&lt;p&gt;Happy Learning 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>devops</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Build your own Shell : PART 2 👨🏾‍💻</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Mon, 06 Nov 2023 09:01:09 +0000</pubDate>
      <link>https://dev.to/angelotheman/build-your-own-shell-part-2-5gie</link>
      <guid>https://dev.to/angelotheman/build-your-own-shell-part-2-5gie</guid>
      <description>&lt;p&gt;In the first part of our journey to create a shell, we explored the basics, crafting a shell that worked when we typed in commands but needed the complete path, like &lt;code&gt;/bin/ls&lt;/code&gt;, to function properly.&lt;/p&gt;

&lt;p&gt;Find the previous article &lt;a href="https://dev.to/angelotheman/build-your-own-shell-part-1-1192"&gt;HERE&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, in this next step, we're going to upgrade our shell to be more flexible and user-friendly:&lt;/p&gt;

&lt;p&gt;We'll make our shell more versatile, allowing it to be used in both interactive chats and automated processes.&lt;br&gt;
We're going to tweak things so that the shell understands simple commands like &lt;code&gt;ls&lt;/code&gt; without needing the whole path, just like we're used to in regular shells.&lt;br&gt;
In a nutshell, we're enhancing our shell to be easier to use and adaptable to different situations. This way, it'll feel more like the shells we commonly use, making our coding journey more exciting and practical.&lt;/p&gt;

&lt;p&gt;Linus Torvalds once said &lt;em&gt;and I want you to note&lt;/em&gt; 👇🏾&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Talk is cheap. Show me the code" - Linus Torvalds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Now let's show the code&lt;/strong&gt; 🔥&lt;/p&gt;

&lt;p&gt;This is our current &lt;code&gt;main.h&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#ifndef MAIN_H
#define MAIN_H

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#endif /* MAIN_H */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and this is our current &lt;code&gt;main.c&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "main.h"

/**
  * main - Getline function
  * @argc: Argument count
  * @argv: Array of argument values
  *
  * Return: 0 on success
  */

int main(int argc, char **argv)
{
        (void)argc, (void)argv;
        char *buf = NULL, *token;
        size_t count = 0;
        ssize_t nread;
        pid_t child_pid;
        int i, status;
        char **array;

        while (1)
        {
                write(STDOUT_FILENO, "MyShell$ ", 9);

                nread = getline(&amp;amp;buf, &amp;amp;count, stdin);

                if (nread ==  -1)
                {
                        perror("Exiting shell");
                        exit(1);
                }

                token = strtok(buf, " \n");

                array = malloc(sizeof(char*) * 1024);
                i = 0;

                while (token)
                {
                        array[i] = token;
                        token = strtok(NULL, " \n");
                        i++;
                }

                array[i] = NULL;

                child_pid = fork();

                if (child_pid == -1)
                {
                        perror("Failed to create.");
                        exit (41);
                }

                if (child_pid == 0)
                {
                        if (execve(path, array, NULL) == -1)
                        {
                                perror("Failed to execute");
                                exit(97);
                        }
                }
                else
                {
                        wait(&amp;amp;status);
                }
        }
        free(buf);
        return (0);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Don't forget we would compile with this command&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gcc -Wall -Wextra -pedantic *.c -o shell &amp;amp;&amp;amp; ./shell


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In order to enhance our shell functionality so that it would work with just the executables eg &lt;code&gt;ls&lt;/code&gt;, I would create a function in a file to handle that.&lt;/p&gt;

&lt;p&gt;In the original shell, when the user inputs &lt;code&gt;ls&lt;/code&gt;, here's what happens&lt;/p&gt;

&lt;p&gt;The shell looks through the &lt;code&gt;PATH&lt;/code&gt; environment variable. The PATH is made up of various directories which contain various executable files. These directories are where the system searches for executable files. When you type a command in the terminal, the system goes through these directories in order until it finds the executable file corresponding to the command you entered. If it doesn't find the command in any of these directories, it will display a "command not found" error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqfqunipiem07nudmdb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqfqunipiem07nudmdb1.png" alt="Image of using the PATH"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are the directories in my PATH&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/home/vagrant/.local/bin:/home/vagrant/.local/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note that they are separated by a colon &lt;code&gt;:&lt;/code&gt;. Hence, in effect, when the user enters &lt;code&gt;ls&lt;/code&gt;, the shell builds an executable path which would be &lt;code&gt;/bin/ls&lt;/code&gt; and runs that instead.&lt;/p&gt;

&lt;p&gt;With this understanding, we need to upgrade our shell with this functionality.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here are the steps that we would take&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;STEP 1&lt;/em&gt;&lt;/strong&gt;: We would get the &lt;code&gt;PATH&lt;/code&gt; variable with the &lt;code&gt;getenv()&lt;/code&gt; command.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;STEP 2&lt;/em&gt;&lt;/strong&gt;: Tokenize each directory in the &lt;code&gt;PATH&lt;/code&gt; with &lt;code&gt;strtok()&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;STEP 3&lt;/em&gt;&lt;/strong&gt;: For each directory, we build an absolute path for the file (user input). Hence if the user input is &lt;code&gt;ls&lt;/code&gt; or &lt;code&gt;hello&lt;/code&gt;, we build an absolute path like so &lt;code&gt;/usr/local/bin/ls&lt;/code&gt; or &lt;code&gt;/usr/local/bin/hello&lt;/code&gt; respectively assuming &lt;code&gt;/usr/local/bin/&lt;/code&gt; is our first directory in the PATH environment.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;STEP 4&lt;/em&gt;&lt;/strong&gt;: After constructing the absolute path above, &lt;code&gt;stat()&lt;/code&gt; is to check the existence of that file in that directory and gather as much information about that file. We then &lt;code&gt;access()&lt;/code&gt; to check if the file is accessible and executable. If either &lt;code&gt;stat()&lt;/code&gt; or &lt;code&gt;access()&lt;/code&gt; fails, then the file is either not found or not executable.&lt;br&gt;
With the example above, &lt;code&gt;/usr/local/bin/hello&lt;/code&gt; is invalid whereas &lt;code&gt;/usr/local/bin/ls&lt;/code&gt; is valid.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;STEP 5&lt;/em&gt;&lt;/strong&gt;: The first instance of the executable file is returned to the &lt;code&gt;execve()&lt;/code&gt;. We would use a function &lt;code&gt;get_file_path&lt;/code&gt; for this and assign its value to a variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: The first argument (array[0]) of the &lt;code&gt;execve()&lt;/code&gt; function is the absolute path of the executable.&lt;/p&gt;

&lt;p&gt;Add this code to the &lt;code&gt;main.c&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/* Initialize the path variable */
char *path;

/* Add this code just after array[i] == NULL */
path = get_file_path(array[0]);

/* Now update the execve to use the path variable like so */
if (execve(path, array, NULL) == -1)
{
    perror("Failed to execute")
    exit(97);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we would code the &lt;code&gt;get_file_path()&lt;/code&gt; function in a different file. Create a file &lt;code&gt;file_loc.c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this file, I would add a helper function to the &lt;code&gt;get_file_path()&lt;/code&gt; named &lt;code&gt;get_file_loc()&lt;/code&gt;. &lt;code&gt;get_file_path()&lt;/code&gt; would retrieve the PATH variable, check whether the PATH exists. If yes, the value of PATH is passed to the &lt;code&gt;get_file_loc()&lt;/code&gt; function would return the full path of the file to the get_file_path.&lt;/p&gt;

&lt;p&gt;To get the PATH as stated in STEP 1 above, we use the &lt;code&gt;getenv()&lt;/code&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getenv()
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/3/getenv" rel="noopener noreferrer"&gt;man 3 getenv&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synopsis&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include &amp;lt;stdlib.h&amp;gt;

char *getenv(const char *name);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;: The &lt;code&gt;getenv()&lt;/code&gt; function searches the environment list to find the environment variable &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Return Value&lt;/strong&gt;: A pointer to the corresponding value of &lt;code&gt;name&lt;/code&gt; or NULL if there's no match.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;file_loc.c&lt;/code&gt; file, let's add the &lt;code&gt;get_file_path&lt;/code&gt; function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "main.h"

/**
  * get_file_path - Get's the full path of the file
  * @file_name: Argument name
  *
  * Return: The full path argument to the file
  */

char *get_file_path(char *file_name)
{
        char *path = getenv("PATH");

        if (!path)
        {
                perror("Path not found");
                return (NULL);
        }

        return (path);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;get_file_path&lt;/code&gt; takes an argument &lt;code&gt;file_name&lt;/code&gt; which would be the input of the user or array[0] used by the &lt;code&gt;execve&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The variable &lt;code&gt;path&lt;/code&gt; stores the value of the &lt;code&gt;getenv("PATH")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A condition is checked for the value returned by the &lt;code&gt;getenv&lt;/code&gt;. If false, the condition is executed ie. The "PATH" value wasn't found.&lt;/li&gt;
&lt;li&gt;We then return the value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: The value we are returning would be something like this&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/home/vagrant/.local/bin:/home/vagrant/.local/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;which is not exactly what we need.&lt;/p&gt;

&lt;p&gt;Hence, we would create another function to help us &lt;strong&gt;tokenize&lt;/strong&gt; this value as stated in STEP 2. After which the same function would help us build an absolute path with the file name which in our case is &lt;code&gt;ls&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add this code to the &lt;code&gt;get_file_path&lt;/code&gt; function&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/* Add to the initialization */
char *full_path;


/* Add this to the function body */
full_path = get_file_loc(path, file_name);

if (full_path == NULL)
{
       perror("Absolute path not found");      
       return (NULL);
}

return (full_path); /* Replace the current return with this */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;We pass the path value and the file_name (&lt;code&gt;ls&lt;/code&gt;) into the &lt;code&gt;get_file_loc&lt;/code&gt; function. This function would help us build the absolute path for the filename &lt;code&gt;ls&lt;/code&gt; after tokenizing the path value.&lt;/li&gt;
&lt;li&gt;The result is stored in the &lt;code&gt;full_path&lt;/code&gt; variable.&lt;/li&gt;
&lt;li&gt;We check if it's null and return NULL if Yes, otherwise we return the &lt;strong&gt;absolute path&lt;/strong&gt; to the function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now in the &lt;code&gt;get_file_loc&lt;/code&gt; function, &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We tokenize the path as stated in STEP 2 with the delimeter &lt;code&gt;:&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;For each directory, we build an absolute path for and append the file_name to the end of it.&lt;/li&gt;
&lt;li&gt;We then use &lt;code&gt;stat&lt;/code&gt; and &lt;code&gt;access&lt;/code&gt; as stated in the STEPS above to check the existence and execute permissions of the file&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Stat
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/2/stat" rel="noopener noreferrer"&gt;man 2 stat&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synopsis&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

int stat(const char *pathname, struct stat *statbuf);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;: Returns the information about the file in the buffer pointed to by the &lt;code&gt;statbuf&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Return Value&lt;/strong&gt;: On success 0, on error -1&lt;/p&gt;

&lt;h3&gt;
  
  
  Access
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/2/access" rel="noopener noreferrer"&gt;man 2 access&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synopsis&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include &amp;lt;unistd.h&amp;gt;

int access(const char *pathname, int mode);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;: This checks whether the file &lt;code&gt;pathname&lt;/code&gt; can be accessed. It has three &lt;code&gt;modes&lt;/code&gt;:&lt;br&gt;
     - F_OK: This tests for the existence of the file&lt;br&gt;
     - R_OK: Tests if file exists and grants read permissions&lt;br&gt;
     - W_OK: Tests if file exists and grants write permissions&lt;br&gt;
     - X_OK: Tests if file exists and grants execute permissions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Return Value&lt;/strong&gt;: 0 if all permissions (modes) specified are met or -1 if at least one fails.&lt;/p&gt;

&lt;p&gt;With this well settled there are other things to consider.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We would create a buffer to hold the absolute path, hence, we would have to &lt;code&gt;malloc&lt;/code&gt; (&lt;a href="https://linux.die.net/man/3/malloc" rel="noopener noreferrer"&gt;man 3 malloc&lt;/a&gt;) memory for that.&lt;/li&gt;
&lt;li&gt;We would have to duplicate using &lt;code&gt;strdup&lt;/code&gt; (&lt;a href="https://linux.die.net/man/3/strdup" rel="noopener noreferrer"&gt;man 3 strdup&lt;/a&gt;) the value from the PATH so that we do not loose it during tokenization.&lt;/li&gt;
&lt;li&gt;We would also perform concatenation using &lt;code&gt;strlen&lt;/code&gt; (&lt;a href="https://linux.die.net/man/3/strdup" rel="noopener noreferrer"&gt;man 3 strlen&lt;/a&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now this is how the &lt;code&gt;get_file_loc&lt;/code&gt; function would look like. Add this to the file &lt;code&gt;file_loc.c&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/**
  * get_file_loc - Get the executable path of file
  * @path: Full path variable
  * @file_name: The executable file
  *
  * Return: Full path to the executable file
  */

char *get_file_loc(char *path, char *file_name)
{
        char *path_copy, *token;
        struct stat file_path;
        char *path_buffer = NULL;

        path_copy = strdup(path);
        token = strtok(path_copy, ":");

        while (token)
        {
                if (path_buffer)
                {
                        free(path_buffer);
                        path_buffer = NULL;
                }
                path_buffer = malloc(strlen(token) + strlen(file_name) + 2);
                if (!path_buffer)
                {
                        perror("Error: malloc failed");
                        exit(EXIT_FAILURE);
                }
                strcpy(path_buffer, token);
                strcat(path_buffer, "/");
                strcat(path_buffer, file_name);
                strcat(path_buffer, "\0");

                if (stat(path_buffer, &amp;amp;file_path) == 0 &amp;amp;&amp;amp; access(path_buffer, X_OK) == 0)
                {
                        free(path_copy);
                        return (path_buffer);
                }
                token = strtok(NULL, ":");
        }
        free(path_copy);
        if (path_buffer)
                free(path_buffer);
        return (NULL);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;We initialize all variables that would be needed.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;struct stat file_path&lt;/code&gt; is a variable used by the &lt;code&gt;stat()&lt;/code&gt; function. &lt;em&gt;See it's implementation in the man page&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;We duplicate the original path and store that in the variable &lt;code&gt;path_copy&lt;/code&gt;. This is done so that we don't loose the original PATH when manipulating it. &lt;code&gt;strdup&lt;/code&gt; allocates memory and the copies the content of the PATH into &lt;code&gt;path_copy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The value of the &lt;code&gt;PATH&lt;/code&gt; is then tokenized with the delimiter &lt;code&gt;:&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;path_buffer&lt;/code&gt; is used to store the absolute path of the executable file input from the user. We need to allocate memory for it and it's size would be the length of the token (eg &lt;code&gt;/usr/bin&lt;/code&gt;), the length of file (eg &lt;code&gt;ls&lt;/code&gt;) and then 2 (because we would add a &lt;code&gt;/&lt;/code&gt; and then end it with a null character &lt;code&gt;\0&lt;/code&gt; to make it a complete string).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;strcpy&lt;/code&gt; and &lt;code&gt;strcat&lt;/code&gt; are used to build this absolute path which would look like &lt;code&gt;/usr/bin/ls&lt;/code&gt; (notice that we added a &lt;code&gt;/&lt;/code&gt; before the &lt;code&gt;ls&lt;/code&gt; and then we completed it with the null character to make it a string).&lt;/li&gt;
&lt;li&gt;After building the absolute path, we use &lt;code&gt;stat&lt;/code&gt; to get more information about the file. We then use &lt;code&gt;access&lt;/code&gt; with the mode &lt;code&gt;X_OK&lt;/code&gt; to check if the file is executable. 
-When these conditions are satisfied, we would &lt;code&gt;free&lt;/code&gt; the path_copy because we allocated space for it and then we return the absolute path which is the &lt;code&gt;path_buffer&lt;/code&gt;. Otherwise, we continue the string tokenization.&lt;/li&gt;
&lt;li&gt;If we didn't get a match for the executable file, we &lt;code&gt;free&lt;/code&gt; the &lt;code&gt;path_copy&lt;/code&gt; and &lt;code&gt;path_buffer&lt;/code&gt; and return &lt;code&gt;NULL&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;That was a lot I know 😀, take your time to re-read it again with understanding&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Don't forget to update your &lt;code&gt;main.h&lt;/code&gt; file to include the headers of our new functions and system calls.&lt;br&gt;
Here's our updated &lt;code&gt;main.h&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#ifndef MAIN_H
#define MAIN_H

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

/* Helper Funcitons */
char *get_file_path(char *file_name);
char *get_file_loc(char *path, char *file_name);

#endif /* MAIN_H */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we would add this to our &lt;code&gt;main.c&lt;/code&gt; file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "main.h"

/**
  * main - Getline function
  * @argc: Argument count
  * @argv: Array of argument values
  *
  * Return: 0 on success
  */

int main(int argc, char **argv)
{
        (void)argc, (void)argv;
        char *buf = NULL, *token, *path;
        size_t count = 0;
        ssize_t nread;
        pid_t child_pid;
        int i, status;
        char **array;

        while (1)
        {
                write(STDOUT_FILENO, "MyShell$ ", 9);

                nread = getline(&amp;amp;buf, &amp;amp;count, stdin);

                if (nread ==  -1)
                {
                        perror("Exiting shell");
                        exit(0);
                }

                token = strtok(buf, " \n");

                array = malloc(sizeof(char*) * 1024);
                i = 0;

                while (token)
                {
                        array[i] = token;
                        token = strtok(NULL, " \n");
                        i++;
                }

                array[i] = NULL;

                path = get_file_path(array[0]); /* Get the absolute path using the function */

                child_pid = fork();

                if (child_pid == -1)
                {
                        perror("Failed to create.");
                        exit (41);
                }

                if (child_pid == 0)
                {
                        if (execve(path, array, NULL) == -1) /* Replace the first argument with that executable file */
                        {
                                perror("Failed to execute");
                                exit(97);
                        }
                }
                else
                {
                        wait(&amp;amp;status);
                }
        }
        free(path);
        free(buf);
        return (0);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  NOTICE THE CHANGES ‼️
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;We pass the first input of the user (array[0]) to the function &lt;code&gt;get_file_path&lt;/code&gt; so that the absolute file path is returned to us.&lt;/li&gt;
&lt;li&gt;We then pass this to the &lt;code&gt;execve&lt;/code&gt; function since it's first argument is supposed to be an executable file/command.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;But there's a slight problem&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
We want our shell to handle user inputs whether it is the absoulute path (&lt;code&gt;/usr/bin/ls&lt;/code&gt;) or just the executable file(&lt;code&gt;ls&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;We would implement a function to help us with that &lt;code&gt;startsWithForwardSlash&lt;/code&gt;. Let's add this to the &lt;code&gt;file_loc.c&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/**
  * startsWithForwardSlash - Checks if file starts with "/"
  * @str: The filename to be checked
  *
  * Return: 0 if yes and 1 if NO
  */

int startsWithForwardSlash(const char *str)
{
        if (str != NULL || str[0] == '/')
                return (1);

        return (0);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;p&gt;This function simply checks the first character of the input string and returns a 1 or 0 if found or not found respectively.&lt;/p&gt;

&lt;p&gt;We would update our &lt;code&gt;get_file_path&lt;/code&gt; function to check if the first character is a &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/* Previous initializations */

if (startsWithForwardSlash(file_name) &amp;amp;&amp;amp; access(file_name, X_OK) == 0)
         return (strdup(file_name));

/* Rest of code */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Hence the full &lt;code&gt;file_loc.c&lt;/code&gt; file would look like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "main.h"

/**
  * startsWithForwardSlash - Checks if file starts with "/"
  * @str: The filename to be checked
  *
  * Return: 0 if yes and 1 if NO
  */

int startsWithForwardSlash(const char *str)
{
        if (str != NULL || str[0] == '/')
                return (1);

        return (0);
}

/**
  * get_file_loc - Get the executable path of file
  * @path: Full path variable
  * @file_name: The executable file
  *
  * Return: Full path to the executable file
  */

char *get_file_loc(char *path, char *file_name)
{
        char *path_copy, *token;
        struct stat file_path;
        char *path_buffer = NULL;

        path_copy = strdup(path);
        token = strtok(path_copy, ":");

        while (token)
        {
                if (path_buffer)
                {
                        free(path_buffer);
                        path_buffer = NULL;
                }
                path_buffer = malloc(strlen(token) + strlen(file_name) + 2);
                if (!path_buffer)
                {
                        perror("Error: malloc failed");
                        exit(EXIT_FAILURE);
                }
                strcpy(path_buffer, token);
                strcat(path_buffer, "/");
                strcat(path_buffer, file_name);
                strcat(path_buffer, "\0");

                if (stat(path_buffer, &amp;amp;file_path) == 0 &amp;amp;&amp;amp; access(path_buffer, X_OK) == 0)
                {
                        free(path_copy);
                        return (path_buffer);
                }
                token = strtok(NULL, ":");
        }
        free(path_copy);
        if (path_buffer)
                free(path_buffer);
        return (NULL);
}

/**
  * get_file_path - Get's the full path of the file
  * @file_name: Argument name
  *
  * Return: The full path argument to the file
  */

char *get_file_path(char *file_name)
{
        char *path = getenv("PATH");
        char *full_path;

        if (startsWithForwardSlash(file_name) &amp;amp;&amp;amp;
                        access(file_name, X_OK) == 0)
                return (strdup(file_name));

        if (!path)
        {
                perror("Path not found");
                return (NULL);
        }

        full_path = get_file_loc(path, file_name);

        if (full_path == NULL)
        {
                write(2, file_name, strlen(file_name));
                write(2, ": command not found\n", 19);
                return (NULL);
        }

        return (full_path);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, we update our &lt;code&gt;main.h&lt;/code&gt; file with the new function&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#ifndef MAIN_H
#define MAIN_H

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

/* Helper Funcitons */
char *get_file_path(char *file_name);
char *get_file_loc(char *path, char *file_name);
int startsWithForwardSlash(const char *str);


#endif /* MAIN_H */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's compile our file with the command &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gcc -Wall -Werror -Wextra -pedantic *.c -o hsh &amp;amp;&amp;amp; ./hsh


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fksjxcsmuhzbguo0s75ux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fksjxcsmuhzbguo0s75ux.png" alt="Result's as at now"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extras
&lt;/h2&gt;

&lt;p&gt;See what happens when you enter the following command in the terminal &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 "ls" | ./hsh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foumbgq5cddikb1xwg3uv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foumbgq5cddikb1xwg3uv.png" alt="Result of command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However we want this to execute the &lt;code&gt;ls&lt;/code&gt; command against the &lt;code&gt;./hsh&lt;/code&gt; executable file. This is known as non-interactive mode.&lt;br&gt;
We would use the &lt;code&gt;isatty&lt;/code&gt; command for this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Isatty
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/3/isatty" rel="noopener noreferrer"&gt;man 3 isatty&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synopsis&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include &amp;lt;unistd.h&amp;gt;

int isatty(int fd);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;:&lt;br&gt;
The isatty() function tests whether fd is an open file descriptor referring to a terminal. This means it checks for the file descriptors - in our case, 0 or STDIN_FILENO, which checks for a file or standard input - and works accordingly.&lt;br&gt;
&lt;strong&gt;Return Value&lt;/strong&gt;:&lt;br&gt;
isatty()  returns 1 if fd is an open file descriptor referring to a terminal; otherwise 0 is returned, and errno is set to indicate the error.&lt;/p&gt;

&lt;p&gt;Let's add the &lt;code&gt;isatty()&lt;/code&gt; function to our main.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/* Add it after the while condition */
if (isatty(STDIN_FILENO))
     write(STDOUT_FILENO, "MyShell$ ", 9);

/* Modify the nread function like so */
if (nread == -1)
{
     exit(1);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;isatty&lt;/code&gt; function works to check whether the file is opened in interactive or non-interactive mode using the file descriptor&lt;/li&gt;
&lt;li&gt;We removed the &lt;code&gt;perror&lt;/code&gt; message in the &lt;code&gt;nread&lt;/code&gt; condition of the &lt;code&gt;getline&lt;/code&gt; function. This is so that we don't get such error messages when exiting the program in either interactive or non-interactive modes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you should get the following output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxdls74rusnyj8999slg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxdls74rusnyj8999slg.png" alt="Result of the function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a summary of all the files&lt;br&gt;
&lt;code&gt;main.c&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "main.h"

/**
  * main - Getline function
  * @argc: Argument count
  * @argv: Array of argument values
  *
  * Return: 0 on success
  */

int main(int argc, char **argv)
{
        (void)argc, (void)argv;
        char *buf = NULL, *token, *path;
        size_t count = 0;
        ssize_t nread;
        pid_t child_pid;
        int i, status;
        char **array;

        while (1)
        {
                if (isatty(STDIN_FILENO))
                        write(STDOUT_FILENO, "MyShell$ ", 9);

                nread = getline(&amp;amp;buf, &amp;amp;count, stdin);

                if (nread ==  -1)
                {
                        exit(0);
                }

                token = strtok(buf, " \n");

                array = malloc(sizeof(char*) * 1024);
                i = 0;

                while (token)
                {
                        array[i] = token;
                        token = strtok(NULL, " \n");
                        i++;
                }

                array[i] = NULL;

                path = get_file_path(array[0]);

                child_pid = fork();

                if (child_pid == -1)
                {
                        perror("Failed to create.");
                        exit (41);
                }

                if (child_pid == 0)
                {
                        if (execve(path, array, NULL) == -1)
                        {
                                perror("Failed to execute");
                                exit(97);
                        }
                }
                else
                {
                        wait(&amp;amp;status);
                }
        }
        free(path);
        free(buf);
        return (0);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;main.h&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#ifndef MAIN_H
#define MAIN_H

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

/* Helper Funcitons */
char *get_file_path(char *file_name);
char *get_file_loc(char *path, char *file_name);
int startsWithForwardSlash(const char *str);


#endif /* MAIN_H */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;file_loc.c&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "main.h"

/**
  * startsWithForwardSlash - Checks if file starts with "/"
  * @str: The filename to be checked
  *
  * Return: 0 if yes and 1 if NO
  */

int startsWithForwardSlash(const char *str)
{
        if (str != NULL || str[0] == '/')
                return (1);

        return (0);
}

/**
  * get_file_loc - Get the executable path of file
  * @path: Full path variable
  * @file_name: The executable file
  *
  * Return: Full path to the executable file
  */

char *get_file_loc(char *path, char *file_name)
{
        char *path_copy, *token;
        struct stat file_path;
        char *path_buffer = NULL;

        path_copy = strdup(path);
        token = strtok(path_copy, ":");

        while (token)
        {
                if (path_buffer)
                {
                        free(path_buffer);
                        path_buffer = NULL;
                }
                path_buffer = malloc(strlen(token) + strlen(file_name) + 2);
                if (!path_buffer)
                {
                        perror("Error: malloc failed");
                        exit(EXIT_FAILURE);
                }
                strcpy(path_buffer, token);
                strcat(path_buffer, "/");
                strcat(path_buffer, file_name);
                strcat(path_buffer, "\0");

                if (stat(path_buffer, &amp;amp;file_path) == 0 &amp;amp;&amp;amp; access(path_buffer, X_OK) == 0)
                {
                        free(path_copy);
                        return (path_buffer);
                }
                token = strtok(NULL, ":");
        }
        free(path_copy);
        if (path_buffer)
                free(path_buffer);
        return (NULL);
}

/**
  * get_file_path - Get's the full path of the file
  * @file_name: Argument name
  *
  * Return: The full path argument to the file
  */

char *get_file_path(char *file_name)
{
        char *path = getenv("PATH");
        char *full_path;

        if (startsWithForwardSlash(file_name) &amp;amp;&amp;amp;
                        access(file_name, X_OK) == 0)
                return (strdup(file_name));

        if (!path)
        {
                perror("Path not found");
                return (NULL);
        }

        full_path = get_file_loc(path, file_name);

        if (full_path == NULL)
        {
                write(2, file_name, strlen(file_name));
                write(2, ": command not found\n", 19);
                return (NULL);
        }

        return (full_path);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Congratulations 👏🏾 you have enhanced your shell. Go ahead and test your shell extensively 🔥.&lt;/p&gt;

&lt;p&gt;In our next article, we would implement other functionalities like &lt;code&gt;exit&lt;/code&gt;, &lt;code&gt;cd&lt;/code&gt;, handling &lt;code&gt;#&lt;/code&gt;, &lt;code&gt;env&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://www.github.com/angelotheman" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, let's get interactive on &lt;a href="https://www.twitter.com/_angelotheman" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and form great connections on &lt;a href="https://www.linkedin.com/in/angelotheman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; 😊&lt;/p&gt;

&lt;p&gt;Happy coding 🥂&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>c</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Build your own Shell : PART 1 👨🏾‍💻</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Wed, 11 Oct 2023 20:22:10 +0000</pubDate>
      <link>https://dev.to/angelotheman/build-your-own-shell-part-1-1192</link>
      <guid>https://dev.to/angelotheman/build-your-own-shell-part-1-1192</guid>
      <description>&lt;p&gt;A shell is a program that provides a user interface to the operating system. It allows users to interact with the system by typing commands. The shell interprets these commands and executes them on behalf of the user.&lt;br&gt;
When a user logs into a system, the shell is typically the first program that is started. The shell then presents the user with a prompt, which is a symbol or sequence of symbols that indicates that the shell is ready to accept a command.&lt;/p&gt;

&lt;p&gt;The user can then type a command and press Enter. The shell will then interpret the command and execute it. If the command is successful, the shell will display the output of the command to the user. If the command is not successful, the shell will display an error message.&lt;/p&gt;

&lt;p&gt;In this article, we are going to build our own Shell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisite
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.datacamp.com/blog/what-is-shell" rel="noopener noreferrer"&gt;What is Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Basic understanding of C programming&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/introduction-of-system-call/" rel="noopener noreferrer"&gt;System Calls&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I would also encourage you to familiarize yourself to use the &lt;code&gt;man&lt;/code&gt; pages to read the implementation of any command you wouldn't understand. I would provide the links at various points in this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started 🔥
&lt;/h2&gt;

&lt;p&gt;Now let's get to the core of building the shell. As we go along, the various system calls I implement would be explained.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Functionality
&lt;/h3&gt;

&lt;p&gt;Let's look at what happens when you enter a command in the shell. Eg.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ls -l


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt;. User enters command &lt;code&gt;ls -l&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;STEP 2&lt;/strong&gt;. The shell &lt;strong&gt;creates a new process(child process)&lt;/strong&gt; using the &lt;code&gt;fork()&lt;/code&gt; function. This creates a copy of the shell process, with its own memory space and program counter.&lt;br&gt;
&lt;strong&gt;STEP 3&lt;/strong&gt;. This &lt;em&gt;child process&lt;/em&gt;, &lt;strong&gt;executes&lt;/strong&gt; the &lt;code&gt;ls&lt;/code&gt; command with another system call (&lt;code&gt;execve&lt;/code&gt;). This replaces the child process's image with the image of the &lt;code&gt;ls&lt;/code&gt; command.&lt;br&gt;
&lt;strong&gt;STEP 4&lt;/strong&gt;. The shell &lt;strong&gt;waits&lt;/strong&gt; for the child process to terminate using the &lt;code&gt;wait()&lt;/code&gt; function. This ensures that the shell does not continue to the next command until the &lt;code&gt;ls&lt;/code&gt; is done executing.&lt;br&gt;
&lt;strong&gt;STEP 5&lt;/strong&gt;. The child process then &lt;strong&gt;parses&lt;/strong&gt; the command line using the &lt;code&gt;strtok()&lt;/code&gt; function. This breaks the command line into individual words and arguments. In our case &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;-l&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;STEP 6&lt;/strong&gt;. The child process executes the &lt;code&gt;ls&lt;/code&gt;, with the &lt;code&gt;-l&lt;/code&gt; argument. This displays a long listing of the content of the current directory.&lt;/p&gt;

&lt;p&gt;As shown in the picture below &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynb48bxxjjgrxawhajtl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynb48bxxjjgrxawhajtl.png" alt="A picture of the result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 7&lt;/strong&gt;. The child process terminates.&lt;br&gt;
&lt;strong&gt;STEP 8&lt;/strong&gt;. The shell continues to wait for the next command from the user.&lt;br&gt;
&lt;strong&gt;STEP 9&lt;/strong&gt;. If the user enters "exit" or &lt;code&gt;Ctrl+D&lt;/code&gt;, the shell exits. This means the &lt;code&gt;EOF&lt;/code&gt; (end-of-file) has been reached. Read more on EOF &lt;a href="https://en.wikipedia.org/wiki/End-of-file#:~:text=In%20computing%2C%20end%2Dof%2D,called%20a%20file%20or%20stream." rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above steps we now understand what happens anytime we interact with the shell.&lt;/p&gt;

&lt;p&gt;Let's start by creating the files we need as seen.&lt;br&gt;
First create a directory named &lt;strong&gt;my_shell&lt;/strong&gt; like so &lt;code&gt;mkdir my_shell&lt;/code&gt;, then add these two files &lt;code&gt;touch main.c&lt;/code&gt; and &lt;code&gt;touch main.h&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's add some codes to both files.&lt;br&gt;
Add this to the &lt;code&gt;main.h&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="cp"&gt;#ifndef MAIN_H
#define MAIN_H
&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#endif &lt;/span&gt;&lt;span class="cm"&gt;/* MAIN_H */&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And to the &lt;code&gt;main.c&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"main.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/**
  * main - Main entry point for our program
  * @argc: Argument count to the main
  * @argv: Pointer to array of argument values
  *
  * Return: O Always success
  */&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDOUT_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyShell$ "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we would execute our program using this command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

gcc &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-Wextra&lt;/span&gt; &lt;span class="nt"&gt;-pedantic&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.c &lt;span class="nt"&gt;-o&lt;/span&gt; shell &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./shell


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This of course would print a simple "#myShell$ " to the screen. Feel free to rename it as you please.&lt;/p&gt;

&lt;p&gt;Following the steps I listed above, we need accept input from the user to be executed. This can be achieved with the function &lt;code&gt;getline()&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Getline()
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/3/getline" rel="noopener noreferrer"&gt;man getline&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synopsis&lt;/strong&gt;:
```man
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;#include &lt;/p&gt;

&lt;p&gt;ssize_t getline(char **lineptr, size_t *n, FILE *stream);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* **Description**: The `getline()` function reads a line of text from a stream. The stream can be a file, a pipe or the standard input (meaning reading what the user enters to the shell like in our case).
* **Return Value**: On success, the number of characters is returned, otherwise -1 on failure.

Let's use this to read input from the user. In the `main.c` file, update the codes to look like so.
```c


int main(int argc, char **argv)
{
        (void)argc, (void)argv;
        char *buf = NULL;
        size_t count = 0;
        ssize_t nread;

        write(STDOUT_FILENO, "MyShell$ ", 9);
        nread = getline(&amp;amp;buf, &amp;amp;count, stdin);

        if (nread ==  -1)
        {
                 perror("Exiting shell");
                 exit(1);
        }
        printf("%s", buf);
        free(buf);
        return (0);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h5&gt;
  
  
  &lt;u&gt;Explanation&lt;/u&gt;
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;argc&lt;/code&gt; and &lt;code&gt;argv&lt;/code&gt; arguments of the main are typecast to void since they are not being used currently.&lt;/li&gt;
&lt;li&gt;We initialize the various variables with their datatypes.&lt;/li&gt;
&lt;li&gt;We first print "MyShell$ " to the screen and wait for the user input.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;getline&lt;/code&gt; function is used to get the user input and it stores it in the &lt;code&gt;buf&lt;/code&gt; variable.

&lt;ul&gt;
&lt;li&gt;buf - Holds the entire user input&lt;/li&gt;
&lt;li&gt;buf_size - This is the number of bytes in the buf&lt;/li&gt;
&lt;li&gt;stdin - This allows us to receive input from the user&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We then store the return value of the &lt;code&gt;getline&lt;/code&gt; in &lt;code&gt;nread&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The condition then checks if &lt;code&gt;getline&lt;/code&gt; failed to read (ie. if it returns -1) as we saw in the return statement, and then prints a system error message using the &lt;code&gt;perror&lt;/code&gt; function (&lt;strong&gt;perror&lt;/strong&gt; is used to print system error messages). &lt;/li&gt;
&lt;li&gt;However if &lt;code&gt;getline&lt;/code&gt; is successful, we want to print the user input.&lt;/li&gt;
&lt;li&gt;Finally, &lt;code&gt;getline&lt;/code&gt; dynamically allocates memory for the &lt;code&gt;buf&lt;/code&gt;, hence we need to &lt;code&gt;free&lt;/code&gt; up that memory and then return 0 to the main.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When this code is compiled and run we should get the following output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekb20g5sgws6ynby0b76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekb20g5sgws6ynby0b76.png" alt="Code Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But wait ✋🏾, our program just exited. That's not how the shell behaves right? We want the user to manually exit the shell by typing "exit", or a combination of "Ctrl + D" which signifies the end-of-file.&lt;/p&gt;

&lt;p&gt;We can solve this adding an infinite &lt;code&gt;while loop&lt;/code&gt; to our program as shown below&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;nread&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDOUT_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyShell$ "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="n"&gt;nread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nread&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Exiting shell"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When this is compiled and executed we should get as shown in the images below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhz6ql98lqsphb4ef0a3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhz6ql98lqsphb4ef0a3r.png" alt="First Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbeyuqna8mjjod0qbhb47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbeyuqna8mjjod0qbhb47.png" alt="Second Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far, our program is reading our input and returning it correctly as supposed.&lt;/p&gt;

&lt;p&gt;Now we would want to execute our program so that when the user inputs a command, a result would be given. As stated in the steps earlier on, our shell would need to create a child process for executing every command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Every process that runs in the shell has a unique identifier known as process ID (PID).  Each process on a system has a unique PID. The PID is used by the operating system to track and manage processes. A process (parent process) can create another process (child process).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Example&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
When a user inputs &lt;code&gt;/bin/ls&lt;/code&gt;, the following happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The shell forks a child process.&lt;/li&gt;
&lt;li&gt;The child process executes the /bin/ls command.&lt;/li&gt;
&lt;li&gt;The child process terminates.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this analogy in place we would go ahead and create a child process which would execute the user input. The function &lt;code&gt;fork()&lt;/code&gt; would be used.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fork()
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/2/fork" rel="noopener noreferrer"&gt;man 2 fork&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synopsis&lt;/strong&gt;:
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  include 
&lt;/h1&gt;

&lt;h1&gt;
  
  
  include 
&lt;/h1&gt;

&lt;p&gt;pid_t fork(void);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* **Description**: The `fork()` function simply creates a child process by duplicating the calling process.
* **Return Value**: On success, the PID (process ID) of the child process is returned in the parent and 0 is returned in the child. Otherwise, -1 is returned to the parent and no child is created.

Once we are able to create the child process, we need to make the parent process wait for the child process to execute. Remember that the child process was created to execute the "/bin/ls" command from the user. To make the parent process wait, we use the function `wait()`;

#### Wait()
[man 2 wait](https://linux.die.net/man/3/wait)
* **Synopsis**:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  include 
&lt;/h1&gt;

&lt;h1&gt;
  
  
  include 
&lt;/h1&gt;

&lt;p&gt;pid_t wait(int *wstatus);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* **Description**: The `wait()` function causes the current process to wait until one of its child processes terminates. When a child process terminates, the wait() function returns the child process's exit status.

The wait() function is typically used to ensure that all of a process's child processes have terminated before the process itself terminates.
* **Return Value**: On success, return PID of the terminated child otherwise -1 on error.

Let's edit the `main.h` file to include the header files which would enable us use the functions we have discussed
```c


#ifndef MAIN_H
#define MAIN_H

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;

#endif /* MAIN_H */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let's implement the &lt;code&gt;fork()&lt;/code&gt; and &lt;code&gt;wait()&lt;/code&gt; in our program.&lt;br&gt;
Update the &lt;code&gt;main.c&lt;/code&gt; file with this code&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;


&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;nread&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="n"&gt;child_pid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDOUT_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyShell$ "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="n"&gt;nread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nread&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Exiting shell"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="n"&gt;child_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child_pid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to create."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;exit&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child_pid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="cm"&gt;/* The creation was successful and we can execute the user input */&lt;/span&gt;
                        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The creation was successful&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="cm"&gt;/* Wait for the child process to execute before terminating the parent process */&lt;/span&gt;
                        &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If the &lt;code&gt;fork()&lt;/code&gt; returns a 0 in the child, the process has been created and hence we can execute the command given by the user. To achieve this, we use the &lt;code&gt;execve()&lt;/code&gt; function.&lt;/p&gt;

&lt;h4&gt;
  
  
  Execve()
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/2/execve" rel="noopener noreferrer"&gt;man 2 execve&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synopsis&lt;/strong&gt;:
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  include 
&lt;/h1&gt;

&lt;p&gt;int execve(const char *pathname, char *const argv[], &lt;br&gt;
          char *const envp[]);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* **Description**: The `execve()` function is typically used to execute a new program referred to by the `pathname` variable as seen above.
     *The pathname is an executable file which is found on your system. 
     * Argv is a an array of strings
     * Envp is also an array of strings (more on that later)
     * Both Argv and Envp should be terminated by a NULL pointer.

Let me explain with an Example.
When the user inputs `ls -l` to the shell, the `fork()` creates the child process to execute that command. When the child process is successfully created (child_pid == 0), the execve function looks for a NULL terminated array format like so `argv = {"ls", "-l", NULL}`. The first argument of the `execve` (pathname) is replaced by `ls` which is argv[0] or the first element in the array argv. 

**NOTE**: This `ls` is an executable file which is found in the `/bin` folder. So when you input `ls` it would give you the same output as `/bin/ls` in the shell (we would implement that later in our shell). Our `execve` function currently accepts only the full path of the executable and therefore `ls` wouldn't work; however `/bin/ls` which is the path of the full executable would work.

* **Return Value**: On success the execve doesn't return, however it returns -1 on error.

Phew! That was a lot 😀. Let's implement it in our `main.c` file
```c


/* Add this code to the condition when child_pid == 0 */
 if (execve(array[0], array, NULL) == -1)
           {
                   perror("Couldn't execute");
                   exit(7);
           }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So far we have seen that the &lt;code&gt;execve&lt;/code&gt; accepts an array of strings which is terminated by the NULL pointer. The question now is, how do we get that array of string inputs. Remember that, the user only inputs &lt;code&gt;/bin/ls -l&lt;/code&gt; and our shell should put this in an array format for the &lt;code&gt;execve&lt;/code&gt; function to use. To accomplish this, we use a function called &lt;code&gt;strtok()&lt;/code&gt; to split the inputs of the user.&lt;/p&gt;

&lt;h4&gt;
  
  
  Strtok()
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://linux.die.net/man/3/strtok" rel="noopener noreferrer"&gt;man 3 strtok&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synopsis&lt;/strong&gt;:
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  include 
&lt;/h1&gt;

&lt;p&gt;char *strtok(char *str, const char *delim);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* **Description**: The `strtok()` function breaks a string into a sequence of tokens. A token is a sequence of characters that is separated from other tokens by a delimiter character (delim). The `strtok()` function returns a pointer to the first token in the string.

The `strtok()` function is typically used to parse strings into individual words or arguments.

In the case of the `/bin/ls -l` command, the *str becomes "/bin/ls" and our delim becomes a space (" "). This means we are separating the string inputs by the space.

The shell uses the strtok() function to parse the command line into the following words and arguments:
`/bin/ls` (command name)
`-l` (argument)
The shell then passes these words and arguments to the execve() function, which executes the `/bin/ls` command with the `-l` argument.

* **Return Value**: On success, the PID (process ID) of the child process is returned in the parent and 0 is returned in the child. Otherwise, -1 is returned to the parent and no child is created.

Let's implement the strtok in our `main.c` file. 
```c


/* Add these initializations just below the main function */
char *token;
char **array;
int i;

/* Add these lines in the while loop after the getline condition */
token = strtok(buf, " \n");

array = malloc(sizeof(char *) * 1024);
i = 0;
while (token)
{
      array[i] = token;
      token = strtok(NULL, " \n");
      i++;
}
array[i] = NULL;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Don't forget to update your &lt;code&gt;main.h&lt;/code&gt; file with this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/* Add this line to the include statements */&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h5&gt;
  
  
  Explanation of the code
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;strtok&lt;/code&gt; takes in the input of the user which has been stored in the &lt;code&gt;buf&lt;/code&gt; and separates it by a space or the newline "\n"(because the user would press ENTER for the command to execute).&lt;/li&gt;
&lt;li&gt;We create an array so we can store the tokens (this would be used by the &lt;code&gt;execve&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Since an array is created, we enter a loop where we assign each token to a space in the array.&lt;/li&gt;
&lt;li&gt;We update the token and set it's first argument to NULL, and then assign the delimiter appropriately. This is found in the usage of &lt;code&gt;strtok()&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;If there are no more tokens (or strings to be parsed), we need to add the NULL pointer to the array per the demands of the &lt;code&gt;execve&lt;/code&gt; function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we have implemented all these functions, this is how your &lt;code&gt;main.h&lt;/code&gt; file should look like.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="cp"&gt;#ifndef MAIN_H
#define MAIN_H
&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/wait.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;span class="cp"&gt;#endif &lt;/span&gt;&lt;span class="cm"&gt;/* MAIN_H */&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is the final code in the &lt;code&gt;main.c&lt;/code&gt; file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"main.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/**
  * main - Getline function
  * @argc: Argument count
  * @argv: Array of argument values
  *
  * Return: 0 on success
  */&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;nread&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="n"&gt;child_pid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDOUT_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"MyShell$ "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="n"&gt;nread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nread&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Exiting shell"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strtok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                        &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strtok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="n"&gt;child_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child_pid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to create."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;exit&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child_pid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;execve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to execute"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                                &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When we compile and execute with&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gcc -Wall -Wextra -pedantic *.c -o shell &amp;amp;&amp;amp; ./shell


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We should get as seen in the images&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kc4egnkuhhmbbktsy2s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kc4egnkuhhmbbktsy2s.png" alt="First Image of Result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w7p42us8fgp9g7hssv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w7p42us8fgp9g7hssv2.png" alt="Second image of result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can test your shell with these commands to make sure it's working&lt;br&gt;
&lt;code&gt;/bin/ls&lt;/code&gt;, &lt;code&gt;/bin/ls -l&lt;/code&gt;, &lt;code&gt;/bin/ls -la&lt;/code&gt;, &lt;code&gt;/bin/pwd&lt;/code&gt;, &lt;code&gt;/bin/echo "Hello World"&lt;/code&gt;, &lt;code&gt;/bin/cat main.c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remember that this is the absolute path of the commands &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;pwd&lt;/code&gt;, &lt;code&gt;echo&lt;/code&gt;, &lt;code&gt;cat&lt;/code&gt; etc. We would add functionalities so that these could give us the results their absolute path gives us.&lt;/p&gt;

&lt;p&gt;Congratulations 👏🏾, you have built a simple shell with basic functionalities.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Shell_(computing)" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;br&gt;
&lt;a href="https://ccsuniversity.ac.in/bridge-library/pdf/microbio-UNIX.pdf" rel="noopener noreferrer"&gt;CS University&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check this out&lt;br&gt;
&lt;a href="https://dev.to/angelotheman/build-your-own-shell-part-2-5gie"&gt;Build your own shell part 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://www.github.com/angelotheman" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, let's get interactive on &lt;a href="https://www.twitter.com/_angelotheman" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and form great connections on &lt;a href="https://www.linkedin.com/in/angelotheman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; 😊&lt;/p&gt;

&lt;p&gt;Happy coding 🥂&lt;/p&gt;

</description>
      <category>c</category>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Exploring File I/O in C📁</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Fri, 06 Oct 2023 08:38:04 +0000</pubDate>
      <link>https://dev.to/angelotheman/exploring-file-io-in-c-1j07</link>
      <guid>https://dev.to/angelotheman/exploring-file-io-in-c-1j07</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;File handling is a fundamental aspect of programming that allows us to interact with data stored on our computers. Whether it's reading text from a file, writing data to it, or manipulating its contents, mastering Input/Output (IO) operations is essential for any developer.&lt;/p&gt;

&lt;p&gt;In this article, we would cover some file handling concepts in C, low-level and high-level File I/O, file descriptors and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importance of File Handling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When a program is terminated, the entire data is lost. Storing in a file will preserve data even if the program terminates.&lt;/li&gt;
&lt;li&gt;If you have to enter a large number of data, it'll take sometime. However, if you have a file containing all the data, you can easily access the contents with few commands.&lt;/li&gt;
&lt;li&gt;File handling enables the reading and writing of configuration files, allowing users to tailor software settings to their preferences.&lt;/li&gt;
&lt;li&gt;Through file handling, programs that need to exchange data with other programs or systems can share data in various formats with external entities.&lt;/li&gt;
&lt;li&gt;Regularly saving data to files ensures that valuable information can be restored in case of system failures or data loss&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started with File Handling
&lt;/h2&gt;

&lt;p&gt;At its core, file handling involves performing operations on files which include &lt;strong&gt;&lt;em&gt;opening, reading, writing and closing&lt;/em&gt;&lt;/strong&gt; files. In C programming, file handling is achieved through the following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streams&lt;/li&gt;
&lt;li&gt;File pointers&lt;/li&gt;
&lt;li&gt;File descriptors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Let's look at these more closely&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Streams
&lt;/h3&gt;

&lt;p&gt;These are a fundamental abstraction for file handling in C. They provide a high-level interface for reading and writing to files. In C, there are standard streams like &lt;code&gt;stdin&lt;/code&gt;(standard input) &lt;code&gt;stdout&lt;/code&gt; (standard output) and &lt;code&gt;stderr&lt;/code&gt; (standard error) which are automatically available for input and output.&lt;/p&gt;

&lt;h3&gt;
  
  
  File Pointers
&lt;/h3&gt;

&lt;p&gt;A file pointer is a mechanism used to keep track of the current position within a file. It determines where the next read or write operation will occur. File pointers are &lt;em&gt;essential&lt;/em&gt; for sequential file access and help navigate through the file's contents.&lt;/p&gt;

&lt;h3&gt;
  
  
  File Descriptors
&lt;/h3&gt;

&lt;p&gt;These are low-level integer identifiers that represent open files in C. Each descriptor corresponds to a particular stream as we found above.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Below is a table to summarize the various descriptors and their corresponding streams.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Integer Value&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Symbolic Constant&lt;/th&gt;
&lt;th&gt;File Stream&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Standard Input&lt;/td&gt;
&lt;td&gt;STDIN_FILENO&lt;/td&gt;
&lt;td&gt;stdin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Standard Output&lt;/td&gt;
&lt;td&gt;STDOUT_FILENO&lt;/td&gt;
&lt;td&gt;stdout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Standard Error&lt;/td&gt;
&lt;td&gt;STDERR_FILENO&lt;/td&gt;
&lt;td&gt;stderr&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;stdin&lt;/code&gt;: It is used to read input from the &lt;em&gt;user&lt;/em&gt; or another program.&lt;br&gt;
&lt;code&gt;stdout&lt;/code&gt;: Used to write output to the &lt;em&gt;user&lt;/em&gt; or another program.&lt;br&gt;
&lt;code&gt;stderr&lt;/code&gt;: Used to write error messages and other diagnostics output to the &lt;em&gt;user&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Basic operations in File handling with C
&lt;/h2&gt;

&lt;p&gt;There are &lt;strong&gt;four (4)&lt;/strong&gt; basic operations in file handling with C. They are opening, reading, writing and closing. These operations must be followed &lt;strong&gt;in order&lt;/strong&gt; when handling and manipulating files.&lt;/p&gt;

&lt;p&gt;Aside the four (4) basic operations, there are generally two (2) approaches to handling them. They are low-level approach with system calls and high-level approach with standard library.&lt;/p&gt;

&lt;p&gt;Another point to note is that files come in different formats such as csv, binary and text. This article would focus on the text files only.&lt;/p&gt;

&lt;p&gt;Let us look at the basic operations in file handling. For each operation, we would look at its implementation in both the high-level and low-level approaches.&lt;/p&gt;
&lt;h3&gt;
  
  
  Opening a File
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is the first step in file handling. It establishes connection between your program and the file on disk.&lt;/li&gt;
&lt;li&gt;During file opening, you specify the following parameters

&lt;ul&gt;
&lt;li&gt;File's name&lt;/li&gt;
&lt;li&gt;Location&lt;/li&gt;
&lt;li&gt;Mode with which you want to open the file in. These modes specify what exactly you would like to do with the file you are opening. These includes: reading only, writing only, appending etc. &lt;a href="https://www.man7.org/linux/man-pages/man3/fopen.3.html"&gt;Man fopen&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  High-Level Approach
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;RETURN VALUE&lt;/em&gt;: FILE pointer if successful, NULL if otherwise&lt;/p&gt;
&lt;h4&gt;
  
  
  Low-Level Approach
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://linux.die.net/man/3/open"&gt;man open&lt;/a&gt;&lt;br&gt;
&lt;em&gt;RETURN VALUE&lt;/em&gt;: New file descriptor if successful, -1 if an error occurred.&lt;/p&gt;

&lt;p&gt;Below is a table to understand various modes and how they correspond to each other in high-level and low-level approaches.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;fopen() mode&lt;/th&gt;
&lt;th&gt;open() flags&lt;/th&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;r&lt;/td&gt;
&lt;td&gt;O_RDONLY&lt;/td&gt;
&lt;td&gt;Opens file for reading&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;r+&lt;/td&gt;
&lt;td&gt;O_RDWR&lt;/td&gt;
&lt;td&gt;Opens file for reading and writing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;w&lt;/td&gt;
&lt;td&gt;O_WRONLY | O_CREAT | O_TRUNC&lt;/td&gt;
&lt;td&gt;Writes to a file. It clears(truncates) everything if there is already text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;w+&lt;/td&gt;
&lt;td&gt;O_RDWR | O_CREAT | O_TRUNC&lt;/td&gt;
&lt;td&gt;Opens for reading and writing. The file is created if it doesn't exist otherwise it's truncated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;td&gt;O_WRONLY | O_CREAT | O_APPEND&lt;/td&gt;
&lt;td&gt;Open for appending (writing at end of file). The file is created if it doesn't exist&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Reading from a File
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This involves retrieving data from existing file on disk.&lt;/li&gt;
&lt;li&gt;You can read data character by character, line by line or in larger chunks depending on your program's requirement.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  High-Level Approach
&lt;/h4&gt;

&lt;p&gt;There are two ways to read from files with this approach. They are:&lt;br&gt;
&lt;strong&gt;fgets()&lt;/strong&gt;: This reads texts line by line and stores in a buffer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// Process each line in the file&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;RETURN VALUE&lt;/em&gt;: A string on success, NULL on error.&lt;br&gt;
&lt;a href="https://linux.die.net/man/3/fgets"&gt;man fgets&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;fread()&lt;/strong&gt;: This reads specified number of bytes from a file or for reading binary files also into a buffer.&lt;br&gt;
&lt;a href="https://www.man7.org/linux/man-pages/man3/fread.3.html"&gt;man fread&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;bytes_to_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_to_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;RETURN VALUE&lt;/em&gt;: Number of items read&lt;/p&gt;

&lt;h4&gt;
  
  
  Low-Level Approach
&lt;/h4&gt;

&lt;p&gt;This uses the &lt;code&gt;read()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_read&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// handle error&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="c1"&gt;// Process the data in the buffer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: The &lt;code&gt;fd&lt;/code&gt; is the return value of the &lt;code&gt;open&lt;/code&gt; function&lt;br&gt;
&lt;a href="https://man7.org/linux/man-pages/man2/read.2.html"&gt;man read&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Writing to a file
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This adds or updates data in a file.&lt;/li&gt;
&lt;li&gt;You can write character by character, line by line or in larger blocks as well.&lt;/li&gt;
&lt;li&gt;Writing is essential for tasks like creating log files, saving program output or storing user-generated content.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  High-Level Approach
&lt;/h4&gt;

&lt;p&gt;This method uses &lt;code&gt;fprintf()&lt;/code&gt; (Write formatted text data to a file)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Open for writing&lt;/span&gt;
&lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello, %s!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://linux.die.net/man/3/fprintf"&gt;man fprintf&lt;/a&gt;&lt;br&gt;
&lt;code&gt;fwrite()&lt;/code&gt; (Writes a specified number of bytes from the buffer to a file)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.bin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wb"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Open for binary writing&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x02&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x03&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;bytes_to_write&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;bytes_written&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_to_write&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://linux.die.net/man/3/fwrite"&gt;man fwrite&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Low-Level Approach
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;write()&lt;/code&gt; is the function used here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_CREAT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_WRONLY&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_TRUNC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;bytes_written&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://linux.die.net/man/2/write"&gt;man write&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Modify the various modes/flags of the write operation to get the desired results like append etc.&lt;/p&gt;

&lt;p&gt;In the low-level approach, you have more control over the writing process and can directly manipulate the binary data. However, you need to manage buffering and handle text encoding yourself if you're working with text files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing a File
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is the final step in the file handling and it's essential to release the system resources and ensure data integrity.&lt;/li&gt;
&lt;li&gt;Once you finish reading or writing, you should close the file to free up the file descriptors and ensure that all pending changes are saved.&lt;/li&gt;
&lt;li&gt;Failing to close a file property can result in resource leaks and data corruption.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  High level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Open for writing&lt;/span&gt;
&lt;span class="c1"&gt;// Write data to the file&lt;/span&gt;
&lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Close the file when done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://linux.die.net/man/3/fclose"&gt;man fclose&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Low level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_CREAT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_WRONLY&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_TRUNC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Open for writing&lt;/span&gt;
&lt;span class="c1"&gt;// Write data to the file&lt;/span&gt;
&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Close the file descriptor when done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://linux.die.net/man/2/close"&gt;man close&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Until now you might have realized that there are two approaches to handline files in C. The commonest one used is the high-level approach. However, let us look at some differences between the two. This would help inform our decisions as to which of them to use at what point in time.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;High level Approach&lt;/th&gt;
&lt;th&gt;Low level Approach&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File representation&lt;/td&gt;
&lt;td&gt;Uses a file stream represented by *FILE**, for file operations&lt;/td&gt;
&lt;td&gt;Uses file descriptors represented by *int* for file operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common functions&lt;/td&gt;
&lt;td&gt;Common functions include fopen(), fclose(), fgets(), fprintf(), fwrite(). &lt;/td&gt;
&lt;td&gt;Common functions include open(), close(), read(), write(). &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text vs. Binary Files&lt;/td&gt;
&lt;td&gt;Suitable for both text and binary files, with functions handling text encoding and formatting. &lt;/td&gt;
&lt;td&gt;Suitable for both text and binary files, but you need to handle text encoding and formatting manually if required. &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error Handling&lt;/td&gt;
&lt;td&gt;Uses functions like ferror() and feof() to handle errors. &lt;/td&gt;
&lt;td&gt;Relies on error codes returned by functions like read() and write() for error handling. &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource Cleanup&lt;/td&gt;
&lt;td&gt;Automatically flushes data and releases resources when you use fclose() &lt;/td&gt;
&lt;td&gt;Requires manual closure of file descriptors using close() for resource cleanup. &lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Now let's look at some examples with practical questions&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;QUESTION 1&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;em&gt;Implement a program to read text from a file&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;SOLUTION&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  High level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: %s source_file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Low level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: %s source_file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;source_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bytes_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDOUT_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;u&gt;&lt;strong&gt;QUESTION 2&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;em&gt;Implement a program to append some text to a file. This program should take the text from the user (stdin) and then append to the file&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;SOLUTION&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  High level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: %s destination_file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter text (Ctrl-D to end):&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Low level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: %s destination_file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;destination_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_WRONLY&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_CREAT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_APPEND&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination_fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter text (Ctrl-D to end):&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination_fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;u&gt;&lt;strong&gt;QUESTION 3&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;em&gt;Implement a File Copy Program (like cp command)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;SOLUTION&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  High level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: %s source_file destination_file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"rb"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"wb"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bytes_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Low level approach
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: %s source_file destination_file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;source_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;destination_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_WRONLY&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_CREAT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_TRUNC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;destination_fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bytes_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination_fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: In low-level implementation, the &lt;code&gt;open()&lt;/code&gt; function has an optional argument known as &lt;em&gt;permissions&lt;/em&gt;. These are file permissions that you can set to the file are read, write and execute permissions represented by their numerical values.&lt;br&gt;
&lt;a href="https://linuxize.com/post/understanding-linux-file-permissions/"&gt;More about file permissions here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikibooks.org/wiki/A_Little_C_Primer/C_File-IO_Through_System_Calls"&gt;C File IO - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/input-output-system-calls-c-create-open-close-read-write/"&gt;GeeksForGeeks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/File_descriptor"&gt;File Descriptor - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations on making it this far 👏🏾. As you have studied, file handling is a very useful programming concept. I would love to know what your experience is with File handling in the comment section.&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://www.github.com/angelotheman"&gt;Github&lt;/a&gt;, let's get interactive on &lt;a href="https://www.twitter.com/_angelotheman"&gt;Twitter&lt;/a&gt; and form great connections on &lt;a href="https://www.linkedin.com/in/angelotheman"&gt;LinkedIn&lt;/a&gt; 😊&lt;/p&gt;

&lt;p&gt;Happy coding 🥂&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>programming</category>
      <category>c</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Art of Clean Code: Mastering the Betty Style 🧑🏾‍💻</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Sun, 16 Jul 2023 22:14:48 +0000</pubDate>
      <link>https://dev.to/angelotheman/the-art-of-clean-code-mastering-the-betty-style-30mo</link>
      <guid>https://dev.to/angelotheman/the-art-of-clean-code-mastering-the-betty-style-30mo</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When it comes to developing software in any programming language, adhering to a consistent coding style is crucial for maintaining readability, collaboration, and code quality. For the C programming language, one widely recognized coding style is known as Betty. Betty, originally created for the Linux kernel development, has become popular within the C programming community, providing a set of guidelines to enhance code clarity and maintainability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Betty?
&lt;/h2&gt;

&lt;p&gt;Betty is a coding style guide specifically tailored for the C programming language. It was devised to standardize coding practices within the Linux kernel development community, ensuring that the codebase is cohesive and comprehensible to developers working on the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Importance of Consistent Style:
&lt;/h2&gt;

&lt;p&gt;Consistency in coding style plays a vital role in collaborative projects, making it easier for team members to understand and modify each other's code. Betty enforces a standardized set of rules, including naming conventions, indentation, spacing, and comment placement. By following these guidelines, developers can produce clean, readable code that is more approachable to others and less prone to errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up betty on local machine.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Clone the &lt;a href="https://github.com/alx-tools/Betty" rel="noopener noreferrer"&gt;betty repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd&lt;/code&gt; into the &lt;code&gt;Betty&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Install the linter with &lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sudo ./install.sh


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the following commands to check if your code/doc fits the Betty Style:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

betty-style &amp;lt;filename&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

betty-doc &amp;lt;filename&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's look at a simple guide for coding using the Betty style&lt;/p&gt;

&lt;h3&gt;
  
  
  Indentation
&lt;/h3&gt;

&lt;p&gt;Imagine looking at a codebase for more than 20hrs. Indentation helps you to easily identify which parts to find information quickly. This really helps with &lt;strong&gt;debugging&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;TAB&lt;/code&gt; to indent your code.
A block of code is every group of statements inside a set of curly braces ({})&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An example is what is used in our &lt;code&gt;main&lt;/code&gt; function&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

int main(void)
{
        return (0);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Do not put multiple statements on a single line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a bad example&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

if (condition) do_this;
do_something_everytime;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is a good example&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

if (condition)
     do_this;

do_something_everytime;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;In the case of multiple indentation statements - the switch statement -, the &lt;code&gt;switch&lt;/code&gt; keyword and it's subordinate &lt;code&gt;case&lt;/code&gt; are placed on the same indentation levels as shown in the example below&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

int add(int sum)
{
        var i = 0;
        switch (sum)
        {
        case 23:
                i = 34;
        default:
                i = 4;
        }
        return var;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  The use of braces {}
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Opening and closing braces should be placed at the beginning of the next line.
This is a bad example 
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;if (condition) {&lt;br&gt;
        statement1;&lt;br&gt;
        statement2;&lt;br&gt;
}&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This a good example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if (condition)&lt;br&gt;
{&lt;br&gt;
        statement1;&lt;br&gt;
        statement2;&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
This applies to functions as well. An example is the main function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;int main(void)&lt;br&gt;
{&lt;br&gt;
        return (0);&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- The body of the braces should be indented as stated in the above examples.

There are exceptions to this rule however. If a continuation of the same statement follows the ending braces, you need to add it. An example is the `do....while` statement. 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;do {&lt;br&gt;
        body of loop;&lt;br&gt;
} while (condition);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Don't use braces for when a single statement is written in 
An example is the code below
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if (condition) &lt;br&gt;
        statement;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It applies to this as well
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if (condition)&lt;br&gt;
        statement;&lt;br&gt;
else&lt;br&gt;
        statement;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Note that this doesn't apply where the even one has multiple statements. An example is
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if (condition)&lt;br&gt;
{&lt;br&gt;
        do_this();&lt;br&gt;
        do_this();&lt;br&gt;
}&lt;br&gt;
else &lt;br&gt;
{&lt;br&gt;
        do_this();&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- Don't use commas on a single line to avoid braces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if (condition) &lt;br&gt;
   do_this(), do_this();&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do this instead 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if (condition) {&lt;br&gt;
        do_this();&lt;br&gt;
        do_this();&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### Use of spaces
- Use space after these keywords `if`, `else if`, `switch`, `case`, `for`, `while`, `return`.
- Do not use space however after the following which look like functions: `sizeof`, `typeof`, `alignof` and `__attribute__`.

Here's a table for reference


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xj08kns1wwrp7mldlb07.png)

However, do not use spaces around (inside) expressions.
This is a bad example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a = sizeof( struct file );&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is a good example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a = sizeof(struct file);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- Use one space around most binary and ternary operators such as : 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;= + - &amp;lt; &amp;gt; * / % | &amp;amp; ^ &amp;lt;= &amp;gt;= == != ? :&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Do not use spaces around **_unary operators_** :
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;amp; * + ~ ! sizeof typeof alignof &lt;strong&gt;attribute&lt;/strong&gt; defined&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- Do not leave trailing whitespace at the end of lines else you'll receive the following warning from betty


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/smy3rpnsw2cpxm573xut.png)

### Breaking of long lines of character
Coding is all about readability and maintainability. Lines of code should not be very long such that one needs to scroll laterally to read them.
The limit on the lines is **80 columns** and is strongly the preferred limit

### Functions
Functions are simply a chunk of code that does one particular thing.
- Functions must contain not more than **40 lines of code**
- Local variables in a function shouldn't exceed `5-10`
- When using source file, **separate functions with one blank line**

### Commenting in C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;/* This is a single line comment */&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is a multiline comment&lt;/li&gt;
&lt;li&gt;comments in C source code
*/&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## Code Documentation
The use of documentation in programming is very necessary for anyone to be able to understand the code very well. We provide documentation by way of commenting. By adding comments at key points, you provide context, explanations, and insights that clarify your code's purpose, intentions and intricacies.

Betty has a style for documenting your code. Let's look at them

### How to document functions
Instead of a regular C multiline commenting, the comment block for the documentation would look like this. 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;main - This is the entry point of the code
*&lt;/li&gt;
&lt;li&gt;Return - 0 Successful
*/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;int main(void)&lt;br&gt;
{&lt;br&gt;
        printf("Hello");&lt;br&gt;
        return (0);&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- If the function must return a value, the `Return:` header tag is **mandatory**

- Arguments supplied to functions must be added to their respective tags.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sum - Calucates the sum of two numbers&lt;/li&gt;
&lt;li&gt;@arg1 - First operand&lt;/li&gt;
&lt;li&gt;@arg2 - Second operand
*&lt;/li&gt;
&lt;li&gt;Return: The sum of the two parameters
*/&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- You could add additional sections like `Example` which you could give examples of the usage of your function

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sum- Makes the sum of two numbers&lt;/li&gt;
&lt;li&gt;@arg1: First operand&lt;/li&gt;
&lt;li&gt;@arg2: Second operand
*&lt;/li&gt;
&lt;li&gt;Return: The sum of two parameters
*&lt;/li&gt;
&lt;li&gt;Example:&lt;/li&gt;
&lt;li&gt;   sum(10, 5); --&amp;gt; 15
*/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;int sum(int num1, int num2)&lt;br&gt;
{&lt;br&gt;
        return (num1 + num2);&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Using the Betty Coding style is extremely beneficial as a programmer. It ensures that your codes are consistent, readable and have great clarity.

I believe this was a great read for you especially if you are a C programmer and a student of ALX Software Engineering and Holberton School. Like and comment if you found it helpful.

Read more about the style of coding from the [Linux Kernel coding style](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/process/coding-style.rst)

Follow me on [Github](https://www.github.com/angelotheman), let's get interractive on [Twitter](https://www.twitter.com/_angelotheman) and form great connections on [LinkedIn](https://www.linkedin.com/in/angelotheman) 😊
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>c</category>
      <category>programming</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Introduction to the Linux Command Line 👨🏾‍💻</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Fri, 14 Jul 2023 07:58:30 +0000</pubDate>
      <link>https://dev.to/angelotheman/introduction-to-the-linux-command-line-2799</link>
      <guid>https://dev.to/angelotheman/introduction-to-the-linux-command-line-2799</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The Linux command line is a powerful tool that lies at the heart of the Linux operating system. It provides users with direct access to the system, enabling them to interact with their computer through a text-based interface. &lt;/p&gt;

&lt;p&gt;While the graphical user interface (GUI) offers convenience and ease of use, the command line remains an essential component for advanced users, administrators, developers, and those seeking efficient and precise control over their Linux environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Linux Command Line (CLI) ❓
&lt;/h2&gt;

&lt;p&gt;The command line is the easiest and fastest way to get things done on practically any operating system.&lt;/p&gt;

&lt;p&gt;I came across these quotes about the Linux CLI which summarizes why you should know how to use the CLI.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give a person a GUI, and they'll click for a day. Teach a person the Linux CLI, and they'll script for a lifetime. ~ Anonymous&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another quote says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the hands of a knowledgeable user, the Linux command line is a powerful tool that can turn the complex into the simple. ~ Larry Wall&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It takes time to get used to the command line. However, a good knowledge of it would greatly enhance your workflow.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here are some advantages of the command line:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CLI allows for faster and more efficient interaction with the computer. With few strokes (literally 😎), you can execute tasks quickly without the need to navigate through menus or click options.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI-based tools and applications generally have lower system resource requirements. CLI programs often consume less memory and processing power, allowing for better resource allocation and system responsiveness.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The CLI excels in automation and scripting capabilities. By combining commands and writing scripts, you can automate repetitive tasks and create complex workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI commands and scripts are portable and reproducible. Scripts written on one Linux machine can be easily executed on another with minimal modifications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI provides access to advanced tools for system monitoring, network diagnostics, text processing, version control, and programming. These tools offer granular control, extensive customization options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Embracing the CLI promotes learning and skill development. It enhances understanding of system operations, file management, and process control. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this series, we will explore the essential concepts, commands, and techniques of the Linux command line. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;We will cover the following:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;File system navigation and manipulation&lt;/li&gt;
&lt;li&gt;Shell permissions and user management&lt;/li&gt;
&lt;li&gt;Shell redirections and text processing&lt;/li&gt;
&lt;li&gt;Shell initialization, variables and expansion&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And many others 🔥&lt;/p&gt;

&lt;p&gt;By the end of this series, you will have a solid foundation to navigate the command line with confidence and leverage its full potential to accomplish your goals efficiently.&lt;/p&gt;

&lt;p&gt;Whether you are a beginner taking your first steps into the Linux command line or an experienced user looking to expand your skills, this guide will provide you with the knowledge and insights necessary to become proficient in the Linux command line. &lt;/p&gt;

&lt;p&gt;So, let's embark on this adventure together and unlock the power and versatility of the Linux command line! 💪🏾&lt;/p&gt;

&lt;p&gt;Let's get interactive on &lt;a href="https://www.twitter.com/_angelotheman"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/angelotheman"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>codenewbie</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Master Git Commands with This Handy Cheat Sheet 📜</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Fri, 30 Jun 2023 15:39:34 +0000</pubDate>
      <link>https://dev.to/angelotheman/master-git-commands-with-this-handy-cheat-sheet-4412</link>
      <guid>https://dev.to/angelotheman/master-git-commands-with-this-handy-cheat-sheet-4412</guid>
      <description>&lt;p&gt;Git, the widely used distributed version control system, has revolutionized the way developers collaborate and manage their codebases. Whether you're a seasoned developer or just starting your coding journey, having a solid understanding of essential Git commands is crucial for maintaining an efficient workflow and ensuring the integrity of your projects.&lt;/p&gt;

&lt;p&gt;As said by Ben Collins-Sussman, &lt;em&gt;Co-founder of Google Code&lt;/em&gt; 👇🏾&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Git is a powerful tool for distributed version control. It is a way to ensure that your project evolves gracefully over time, no matter how many people are working on it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Now steal this git cheat sheet I prepared for you 😀&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🔗&lt;strong&gt;Configurations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure your name. This would serve as the author of the commit : &lt;code&gt;git config --global user.name "[fistname lastname]"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Configure your email. This would serve as the email of the author : &lt;code&gt;git config --global user.email "[your_email]"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🌱&lt;strong&gt;Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize a new Git repository : &lt;code&gt;git init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a local copy of a remote repository : &lt;code&gt;git clone &amp;lt;repository_url&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add a remote repository : &lt;code&gt;git remote add &amp;lt;remote_name&amp;gt; &amp;lt;remote_url&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📝&lt;strong&gt;Basic Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a file to the staging area : &lt;code&gt;git add &amp;lt;filename&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;all&lt;/strong&gt; files to the staging area : &lt;code&gt;git add .&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Commit changes to the repository : &lt;code&gt;git commit -m "[commit_message]"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔁&lt;strong&gt;Updating and Publishing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Publish all local commits to a remote branch : &lt;code&gt;git push &amp;lt;remote_name&amp;gt; &amp;lt;branch_name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Publish all local commits to a new branch : &lt;code&gt;git push -u &amp;lt;remote_name&amp;gt; &amp;lt;branch_name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Update the local repository : &lt;code&gt;git pull&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Download remote changes without merging : &lt;code&gt;git fetch&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🌿&lt;strong&gt;Branches&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new branch : &lt;code&gt;git branch &amp;lt;branch_name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Switch to a branch : &lt;code&gt;git checkout &amp;lt;branch_name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a new branch and switch to it : &lt;code&gt;git checkout -b &amp;lt;branch_name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;List all the branches : &lt;code&gt;git branch -a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Determine your current branch : &lt;code&gt;git branch&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔀&lt;strong&gt;Merging&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Combine changes of one branch to your current branch : &lt;code&gt;git merge &amp;lt;branch_name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Reapply commits on top of another base commit : &lt;code&gt;git rebase &amp;lt;branch_name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔃&lt;strong&gt;Resets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discard all local changes : &lt;code&gt;git reset --hard HEAD&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔍&lt;strong&gt;Status and History&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View the status of the working directory : &lt;code&gt;git status&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Show difference between commits or the working directory : &lt;code&gt;git diff&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Show commit history : &lt;code&gt;git log&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Display who last modified each line of a file : &lt;code&gt;git blame&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💼&lt;strong&gt;Additional commands&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove untracked files : &lt;code&gt;git clean -f&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Useful tips ✍🏾
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Don’t EVER commit private keys / Api keys / certificates.&lt;/li&gt;
&lt;li&gt;Use descriptive commit messages and branch names.&lt;/li&gt;
&lt;li&gt;Create a branch for every new feature, and delete the branch once the feature is merged into main.&lt;/li&gt;
&lt;li&gt;Ignore some files using a &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Regularly update and sync with remote repositories&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://www.atlassian.com/git/tutorials/git-alias"&gt;git alias&lt;/a&gt; for frequently used commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Visit &lt;a href="https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet"&gt;Atlassian&lt;/a&gt; or &lt;a href="https://education.github.com/git-cheat-sheet-education.pdf"&gt;GitHub Education&lt;/a&gt; to read more on other advanced git commands&lt;/em&gt;🔥&lt;/p&gt;

&lt;p&gt;In conclusion, mastering Git commands is crucial for efficient version control and collaboration in software development, enabling developers to effectively manage projects and streamline workflows.&lt;/p&gt;

&lt;p&gt;Did you learn anything new ❓ Share it in the comments. &lt;/p&gt;

&lt;p&gt;Let's get interactive on &lt;a href="https://www.twitter.com/_angelotheman"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/angelotheman"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow my projects on &lt;a href="https://www.github.com/angelotheman"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding 👨🏾‍💻&lt;/p&gt;

</description>
      <category>git</category>
      <category>programming</category>
      <category>codenewbie</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Flowchart Wizardry: Master the Art of Visualizing Algorithms 😎</title>
      <dc:creator>Angel Oduro-Temeng Twumasi</dc:creator>
      <pubDate>Tue, 27 Jun 2023 19:16:54 +0000</pubDate>
      <link>https://dev.to/angelotheman/flowchart-wizardry-master-the-art-of-visualizing-algorithms-4e4j</link>
      <guid>https://dev.to/angelotheman/flowchart-wizardry-master-the-art-of-visualizing-algorithms-4e4j</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/angelotheman/from-logic-to-lines-unleashing-the-power-of-pseudocode-and-flow-charts-in-development-2615"&gt;In my previous article&lt;/a&gt;, we looked at Pseudocode and its application in problem solving as a developer. &lt;br&gt;
In this article, we would consider Flow charts, which is basically the graphical representation of Pseudocode. &lt;/p&gt;

&lt;h2&gt;
  
  
  Flowcharts Explained
&lt;/h2&gt;

&lt;p&gt;Flowcharts makes it easier for developers to communicate clearly the algorithm used to solve a particular problem. This in turn makes it easier for the audience to grasp the concepts and for other developers to easily code this out.&lt;/p&gt;

&lt;p&gt;Flow charts are a part of the &lt;a href="https://www.tutorialspoint.com/uml/index.htm" rel="noopener noreferrer"&gt;Unified Modelling Language&lt;/a&gt;, which provides a broader range of diagrams that cover various aspects of system design and modelling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uses of Flow charts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Flow charts provide a visual representation of all processes or workflows used to solve a problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They serve as a common language for sharing and discussing problems. This means, they are not tied to a specific programming language and hence makes collaboration and communication easier between other developers and stakeholders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They also serve as great tools for education and training purposes especially for beginner programmers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Flow Chart Symbols
&lt;/h2&gt;

&lt;p&gt;For flow charts to foster easy communication of thought process of developers, there must be guidelines for this.&lt;/p&gt;

&lt;p&gt;Let's have a look at the six (6) basic symbols which are widely used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidiehvnn1ltojcpb77k1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidiehvnn1ltojcpb77k1.png" alt="An image description of 6 basic flow chart symbols used"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's explain them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;Terminator&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;: This represents the start and end points of the flow diagram / algorithm that is represented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;Decision&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;: This represents a question to be answered either &lt;strong&gt;YES&lt;/strong&gt; or &lt;strong&gt;NO&lt;/strong&gt;. The flowchart path may split to different branches depending on the answer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;Process&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;: This represents an action taken or a function. It is the most widely used of all the symbols.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;Document&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;: This is used to indicate a point in the process where information is documented or recorded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;Data&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;: This represents the input of data into the flowchart. This input is then processed in the flowchart.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;Direction of flow&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;: As the name clearly suggests, it determines where every process leads. This makes it easier to trace the logic being explained to solve a particular problem.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://asana.com/resources/what-is-a-flowchart" rel="noopener noreferrer"&gt;Read more about flow chart symbols here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to draw flowcharts
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clearly understand the process or algorithm you want to represent in the flowchart. Identify the starting point.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identify the symbols needed. Each symbol represents a specific action or decision point in the process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start with the start/end symbols. Place them at the beginning and the end of the flowchart.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add process, decision symbols as and when necessary. Also include input/output if the process requires a user input or generates output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add annotations if needed to provide additional details about specific steps.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Worked Examples
&lt;/h2&gt;

&lt;p&gt;In this section, we would solve the same problems in &lt;a href="https://dev.to/angelotheman/from-logic-to-lines-unleashing-the-power-of-pseudocode-and-flow-charts-in-development-2615"&gt;my previous article&lt;/a&gt; using flowcharts.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Problem Statement 1&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;em&gt;Write an algorithm to calculate the product of two numbers given by a user&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6ewlk8kc0gvxooygyc6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6ewlk8kc0gvxooygyc6.png" alt="Solution to Problem 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Problem Statement 2&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;em&gt;Write an algorithm that reads 3 numbers and writes them all in a sorted order&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f5owhow9swpea5do7eu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f5owhow9swpea5do7eu.png" alt="Solution to Problem 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Problem Statement 3&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;em&gt;Write an algorithm to print the first 20 numbers in the Fibonacci sequence (&lt;a href="https://en.wikipedia.org/wiki/Fibonacci_sequence" rel="noopener noreferrer"&gt;Read about the Fibonacci sequence&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0989ajo1lsm1aahgi7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0989ajo1lsm1aahgi7j.png" alt="Solution to Problem 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Problem Statement 4&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;em&gt;Develop an algorithm to calculate a running sum&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you wrote the Pseudocode for this in my previous article, go ahead and translate this into the flowchart. Drop your shareable link in the comment section.&lt;/p&gt;

&lt;p&gt;You can use the following to draw the charts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.lucidchart.com/pages/" rel="noopener noreferrer"&gt;Lucid Charts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.diagrams.net/" rel="noopener noreferrer"&gt;Draw io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flowcharts serve as a powerful visual tool for representing the logic of an algorithm or process. They offer a clear and concise way to communicate complex ideas, making them an invaluable asset in various fields, including software development, engineering, project management, and problem-solving.&lt;/p&gt;

&lt;p&gt;Let's get interactive on &lt;a href="https://www.twitter.com/_angelotheman" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/angelotheman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow me if you found this content helpful 🤝.&lt;/p&gt;

&lt;p&gt;Happy programming 🥂&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>codenewbie</category>
      <category>algorithms</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
