<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[DevOps & Cloud Chronicles]]></title><description><![CDATA[DevOps & Cloud Chronicles]]></description><link>https://intro-to-devops-legacy-to-modern.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 20 Jun 2026 19:54:14 GMT</lastBuildDate><atom:link href="https://intro-to-devops-legacy-to-modern.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Linux Basics for DevOps Beginners]]></title><description><![CDATA[Introduction
In DevOps, Linux is a fundamental skill because most servers, cloud instances, and tools run on Linux-based systems. Today, we’ll dive deep into essential Linux commands, the vim editor, and user management. These skills are critical for...]]></description><link>https://intro-to-devops-legacy-to-modern.hashnode.dev/linux-basics-for-devops-beginners</link><guid isPermaLink="true">https://intro-to-devops-legacy-to-modern.hashnode.dev/linux-basics-for-devops-beginners</guid><category><![CDATA[#linux-basics-for-devops-beginners]]></category><category><![CDATA[Linux]]></category><category><![CDATA[user management]]></category><dc:creator><![CDATA[ESHNITHIN YADAV]]></dc:creator><pubDate>Thu, 01 May 2025 18:30:00 GMT</pubDate><content:encoded><![CDATA[<h4 id="heading-introduction">Introduction</h4>
<p>In DevOps, Linux is a fundamental skill because most servers, cloud instances, and tools run on Linux-based systems. Today, we’ll dive deep into essential Linux commands, the <code>vim</code> editor, and user management. These skills are critical for a DevOps engineer to manage files, edit configurations, and control team access on a server.</p>
<hr />
<h4 id="heading-understanding-the-linux-environment">Understanding the Linux Environment</h4>
<h5 id="heading-user-types-and-directories">User Types and Directories</h5>
<ul>
<li><p><strong>Normal User ($)</strong>: A regular user with limited permissions. Their home directory is typically <code>/home/username</code>. For example, if my username is <code>suresh</code>, my home directory is <code>/home/suresh</code>.</p>
</li>
<li><p><strong>Root User (#)</strong>: The admin or superuser with unrestricted permissions. Their home directory is <code>/root</code>. As the root user, I can perform any action, such as installing software or deleting critical system files.</p>
</li>
<li><p><strong>Root Directory (/)</strong>: The top-level directory in Linux, analogous to the "C:" drive in Windows. All other directories (e.g., <code>/home</code>, <code>/etc</code>, <code>/var</code>) are nested within it.</p>
</li>
</ul>
<p><strong>Example</strong>: If I log in as <code>suresh</code>, my terminal prompt might look like <code>suresh@my-server:~$</code>, where <code>$</code> indicates I’m a normal user. If I switch to the root user with <code>sudo -i</code>, the prompt changes to <code>root@my-server:/root#</code>, where <code>#</code> indicates I’m the root user.</p>
<h5 id="heading-command-structure">Command Structure</h5>
<p>Linux commands follow this format:<br /><code>command &lt;options&gt; &lt;inputs&gt;</code></p>
<ul>
<li><p><strong>Command</strong>: The action to perform (e.g., <code>ls</code> to list files).</p>
</li>
<li><p><strong>Options</strong>: Flags to modify the command’s behavior (e.g., <code>-l</code> for a detailed list).</p>
</li>
<li><p><strong>Inputs</strong>: The target of the action (e.g., a file or directory name).</p>
</li>
</ul>
<p><strong>Example</strong>: <code>ls -l /home</code> lists the contents of <code>/home</code> in a detailed (long) format.</p>
<hr />
<h4 id="heading-basic-linux-commands">Basic Linux Commands</h4>
<p>Let’s explore essential Linux commands with detailed examples, showing the exact commands, their execution, and the resulting outputs.</p>
<h5 id="heading-listing-files-with-ls">Listing Files with <code>ls</code></h5>
<p>The <code>ls</code> command lists files and directories in your current directory. It’s one of the most frequently used commands in Linux. Here are its key variations:</p>
<p><code>ls -l</code>: Shows a long listing with details like permissions, owner, size, and modification date, sorted alphabetically by default.<br /><strong>What Happens</strong>: It displays each file or directory on a new line with detailed information.<br /><strong>Example</strong>: Suppose my current directory (<code>/home/suresh</code>) contains two files (<code>file1.txt</code>, <code>file2.txt</code>) and a folder (<code>docs</code>). I create them with specific sizes and timestamps to match the scenario:</p>
<pre><code class="lang-plaintext">printf "123456789\n" &gt; file1.txt              # 10 bytes (9 chars + newline)
printf "1234567890123456789\n" &gt; file2.txt    # 20 bytes (19 chars + newline)
mkdir docs
touch -t 202505290041 file1.txt               # 2 minutes ago
touch -t 202505290042 file2.txt               # 1 minute ago
touch -t 202505290043 docs                    # Current time
ls -l
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">drwxr-xr-x 2 suresh suresh 4096 May 29 00:43 docs
-rw-r--r-- 1 suresh suresh   10 May 29 00:41 file1.txt
-rw-r--r-- 1 suresh suresh   20 May 29 00:42 file2.txt
</code></pre>
<ul>
<li><p><strong>Order</strong>: Alphabetical (<code>docs</code>, <code>file1.txt</code>, <code>file2.txt</code>) since <code>d</code> comes before <code>f</code>, and <code>file1.txt</code> comes before <code>file2.txt</code> (1 before 2 in ASCII).</p>
</li>
<li><p><strong>Fields</strong>:</p>
<ul>
<li><p><code>drwxr-xr-x</code> or <code>-rw-r--r--</code>: Permissions (<code>d</code> for directory; owner has read/write, others have read; directory has execute permissions for navigation).</p>
</li>
<li><p><code>1</code> or <code>2</code>: Number of links (<code>1</code> for files, <code>2</code> for an empty directory due to <code>.</code> entry).</p>
</li>
<li><p><code>suresh suresh</code>: Owner and group.</p>
</li>
<li><p><code>10</code>, <code>20</code>, <code>4096</code>: File sizes in bytes.</p>
</li>
<li><p><code>May 29 00:41</code> to <code>00:43</code>: Last modified dates.</p>
</li>
<li><p><code>docs</code>, <code>file1.txt</code>, <code>file2.txt</code>: Names.</p>
</li>
</ul>
</li>
</ul>
<p><code>ls -lr</code>: Long listing in reverse alphabetical order.<br /><strong>What Happens</strong>: Same as <code>ls -l</code>, but the order is reversed.<br /><strong>Example</strong>: Using the same directory:</p>
<pre><code class="lang-plaintext">ls -lr
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh   20 May 29 00:42 file2.txt
-rw-r--r-- 1 suresh suresh   10 May 29 00:41 file1.txt
drwxr-xr-x 2 suresh suresh 4096 May 29 00:43 docs
</code></pre>
<ul>
<li><strong>Order</strong>: Reverse alphabetical (<code>file2.txt</code>, <code>file1.txt</code>, <code>docs</code>).</li>
</ul>
<p><code>ls -lt</code>: Long listing, sorted by modification time, newest first.<br /><strong>What Happens</strong>: Files are sorted by their last modified time, not alphabetically.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">ls -lt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">drwxr-xr-x 2 suresh suresh 4096 May 29 00:43 docs
-rw-r--r-- 1 suresh suresh   20 May 29 00:42 file2.txt
-rw-r--r-- 1 suresh suresh   10 May 29 00:41 file1.txt
</code></pre>
<ul>
<li><strong>Order</strong>: Newest to oldest (<code>docs</code> at 00:43, <code>file2.txt</code> at 00:42, <code>file1.txt</code> at 00:41).</li>
</ul>
<p><code>ls -ltr</code>: Long listing, sorted by time, oldest first (newest at the bottom).<br /><strong>What Happens</strong>: Same as <code>ls -lt</code>, but the order is reversed.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">ls -ltr
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh   10 May 29 00:41 file1.txt
-rw-r--r-- 1 suresh suresh   20 May 29 00:42 file2.txt
drwxr-xr-x 2 suresh suresh 4096 May 29 00:43 docs
</code></pre>
<ul>
<li><strong>Order</strong>: Oldest to newest (<code>file1.txt</code>, <code>file2.txt</code>, <code>docs</code>).</li>
</ul>
<p><code>ls -la</code>: Shows all files, including hidden ones (files starting with a dot, like <code>.bashrc</code>), in long format.<br /><strong>What Happens</strong>: It lists everything, including hidden files that <code>ls -l</code> skips.<br /><strong>Example</strong>: Add a hidden file <code>.config</code> (50 bytes, same timestamp as <code>file1.txt</code>):</p>
<pre><code class="lang-plaintext">printf "1234567890123456789012345678901234567890123456789\n" &gt; .config  # 50 bytes
touch -t 202505290041 .config
ls -la
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">drwxr-xr-x 3 suresh suresh 4096 May 29 00:43 .
drwxr-xr-x 5 root  root  4096 May 29 00:00 ..
-rw-r--r-- 1 suresh suresh   50 May 29 00:41 .config
drwxr-xr-x 2 suresh suresh 4096 May 29 00:43 docs
-rw-r--r-- 1 suresh suresh   10 May 29 00:41 file1.txt
-rw-r--r-- 1 suresh suresh   20 May 29 00:42 file2.txt
</code></pre>
<ul>
<li><p><strong>Order</strong>: Alphabetical, including hidden files (<code>.</code>, <code>..</code>, <code>.config</code>, <code>docs</code>, <code>file1.txt</code>, <code>file2.txt</code>).</p>
</li>
<li><p><strong>Notes</strong>: <code>.</code> (current directory) and <code>..</code> (parent directory) are always shown with <code>-a</code>.</p>
</li>
</ul>
<p><strong>Why Useful in DevOps?</strong>: I use <code>ls -lt</code> to find the latest logs on a server (e.g., <code>/var/log</code>), <code>ls -la</code> to check for hidden config files, and <code>ls -l</code> to verify file ownership before changing permissions.</p>
<hr />
<h5 id="heading-creating-and-modifying-files">Creating and Modifying Files</h5>
<p><code>touch &lt;file-name&gt;</code>: Creates an empty file or updates the timestamp of an existing file.<br /><strong>What Happens</strong>: If the file doesn’t exist, it creates a new empty file. If it exists, it updates the "last modified" timestamp to the current time.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">touch newfile.txt
ls -l newfile.txt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh    0 May 29 00:43 newfile.txt
</code></pre>
<ul>
<li>The file is created with size 0 (empty). If I run <code>touch newfile.txt</code> again (e.g., at 00:44):</li>
</ul>
<pre><code class="lang-plaintext">touch newfile.txt
ls -l newfile.txt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh    0 May 29 00:44 newfile.txt
</code></pre>
<ul>
<li>The timestamp updates to the current time.</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I might use <code>touch</code> to create a placeholder file or update a file’s timestamp to trigger a monitoring script.</p>
<p><code>cat &gt; &lt;file-name&gt;</code>: Creates a file (or overwrites it if it exists) and lets you type text. Press <code>Ctrl+D</code> to save.<br /><strong>What Happens</strong>: It opens an input mode where you type text, and when you save, the file is created or overwritten with that text.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">cat &gt; myfile.txt
Hello, DevOps!
&lt;Ctrl+D&gt;
cat myfile.txt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">Hello, DevOps!
</code></pre>
<ul>
<li>If <code>myfile.txt</code> already had content (e.g., "Old text"), it’s overwritten with "Hello, DevOps!".</li>
</ul>
<p><strong>Why Useful?</strong>: I might use this to quickly create a small config file on a server.</p>
<p><code>cat &gt;&gt; &lt;file-name&gt;</code>: Appends text to a file without overwriting it.<br /><strong>What Happens</strong>: It adds your new text to the end of the file, keeping existing content.<br /><strong>Example</strong>: Starting with <code>myfile.txt</code> from above:</p>
<pre><code class="lang-plaintext">cat &gt;&gt; myfile.txt
I’m learning Linux!
&lt;Ctrl+D&gt;
cat myfile.txt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">Hello, DevOps!
I’m learning Linux!
</code></pre>
<ul>
<li>The new text is appended on a new line.</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I might append error messages to a log file without losing previous entries.</p>
<p><strong>Redirection Explained</strong>: The <code>&gt;</code> symbol redirects output to a file, overwriting it, while <code>&gt;&gt;</code> appends. For example:</p>
<ul>
<li><p><code>echo "Test" &gt; test.txt</code> creates/overwrites <code>test.txt</code> with "Test".</p>
</li>
<li><p><code>echo "More" &gt;&gt; test.txt</code> appends "More", resulting in:</p>
<pre><code class="lang-plaintext">  Test
  More
</code></pre>
</li>
</ul>
<hr />
<h5 id="heading-managing-files-and-directories-crud-operations">Managing Files and Directories (CRUD Operations)</h5>
<p>CRUD stands for Create, Read, Update, Delete—basic operations for managing files and folders.</p>
<p><code>mkdir &lt;name&gt;</code>: Creates a directory.<br /><strong>What Happens</strong>: It creates a new folder in your current directory.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">mkdir myproject
ls -l
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">drwxr-xr-x 2 suresh suresh 4096 May 29 00:43 myproject
</code></pre>
<ul>
<li>A new directory named <code>myproject</code> is created. If I run <code>mkdir myproject</code> again:</li>
</ul>
<pre><code class="lang-plaintext">mkdir myproject
</code></pre>
<p><strong>Output (Error)</strong>:</p>
<pre><code class="lang-plaintext">mkdir: cannot create directory ‘myproject’: File exists
</code></pre>
<p><strong>Why Useful?</strong>: In DevOps, I might create a directory to store application files, like <code>mkdir /var/www/myapp</code>.</p>
<p><code>rmdir &lt;directory-name&gt;</code>: Removes an empty directory.<br /><strong>What Happens</strong>: It deletes the directory, but only if it’s empty (no files or subdirectories inside).<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">rmdir myproject
ls -l
</code></pre>
<p><strong>Output</strong>: <code>myproject</code> is no longer listed—it’s deleted. If <code>myproject</code> had files inside (e.g., <code>touch myproject/file.txt</code>):</p>
<pre><code class="lang-plaintext">rmdir myproject
</code></pre>
<p><strong>Output (Error)</strong>:</p>
<pre><code class="lang-plaintext">rmdir: failed to remove 'myproject': Directory not empty
</code></pre>
<p><strong>Why Useful?</strong>: I might use this to clean up empty directories after a project ends, but it’s limited since it only works on empty directories.</p>
<p><code>rm -f &lt;file-name&gt;</code>: Forcefully deletes a file without asking for confirmation.<br /><strong>What Happens</strong>: It deletes the file immediately, even if it’s write-protected, without prompting.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">touch file1.txt
rm -f file1.txt
ls -l
</code></pre>
<p><strong>Output</strong>: <code>file1.txt</code> is no longer listed—it’s deleted. Without <code>-f</code>, if the file is write-protected (e.g., <code>chmod 444 file1.txt</code>), <code>rm</code> might prompt for confirmation, but <code>-f</code> skips that.</p>
<p><strong>Why Useful?</strong>: In DevOps, I might use <code>rm -f</code> in a script to delete temporary files without interruptions.</p>
<p><code>rm -rf &lt;directory-name&gt;</code>: Recursively and forcefully deletes a directory and all its contents.<br /><strong>What Happens</strong>: It deletes the directory, all files, and subdirectories inside it, without asking for confirmation. <strong>Be very careful—this cannot be undone!</strong><br /><strong>Example</strong>: Suppose <code>myproject</code> contains:</p>
<pre><code class="lang-plaintext">myproject/
├── file1.txt
└── subfolder/
    └── file2.txt
</code></pre>
<p>I create this structure:</p>
<pre><code class="lang-plaintext">mkdir -p myproject/subfolder
touch myproject/file1.txt myproject/subfolder/file2.txt
</code></pre>
<p>Then run:</p>
<pre><code class="lang-plaintext">rm -rf myproject
ls -l
</code></pre>
<p><strong>Output</strong>: The entire <code>myproject</code> directory and its contents are gone—nothing named <code>myproject</code> is listed anymore.</p>
<p><strong>Why Useful?</strong>: In DevOps, I might use this to clean up a project directory before redeploying an application, but I always double-check to avoid deleting critical data.</p>
<p><code>cp &lt;source&gt; &lt;destination&gt;</code>: Copies files or folders.<br /><strong>What Happens</strong>: It creates a copy of the source at the destination. Use <code>-r</code> for directories to copy recursively (including subdirectories).<br /><strong>Example (File Copy)</strong>:</p>
<pre><code class="lang-plaintext">touch file1.txt
cp file1.txt file1_backup.txt
ls -l
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh    0 May 29 00:43 file1.txt
-rw-r--r-- 1 suresh suresh    0 May 29 00:43 file1_backup.txt
</code></pre>
<p><strong>Example (Directory Copy)</strong>:</p>
<pre><code class="lang-plaintext">mkdir source_dir
touch source_dir/file.txt
cp -r source_dir dest_dir
ls -l dest_dir
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh    0 May 29 00:43 file.txt
</code></pre>
<ul>
<li>The entire <code>source_dir</code> structure is copied to <code>dest_dir</code>.</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I might back up a config file before editing it, like <code>cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak</code>.</p>
<p><code>mv &lt;source&gt; &lt;destination&gt;</code>: Moves or renames files/folders (like cut and paste).<br /><strong>What Happens</strong>: It moves the source to the destination, deleting the source from its original location. It can also rename if the destination is a new name in the same directory.<br /><strong>Example (Rename)</strong>:</p>
<pre><code class="lang-plaintext">touch file1.txt
mv file1.txt file2.txt
ls -l
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh    0 May 29 00:43 file2.txt
</code></pre>
<ul>
<li><code>file1.txt</code> is renamed to <code>file2.txt</code>.</li>
</ul>
<p><strong>Example (Move)</strong>:</p>
<pre><code class="lang-plaintext">mkdir new_dir
mv file2.txt new_dir/
ls -l
ls -l new_dir
</code></pre>
<p><strong>Output (Current Directory)</strong>:</p>
<pre><code class="lang-plaintext">drwxr-xr-x 2 suresh suresh 4096 May 29 00:43 new_dir
</code></pre>
<p><strong>Output (Inside</strong> <code>new_dir</code>):</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh    0 May 29 00:43 file2.txt
</code></pre>
<ul>
<li><code>file2.txt</code> is moved into <code>new_dir</code>.</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I might use <code>mv</code> to move log files to an archive directory, like <code>mv /var/log/app.log /archive/app.log.2025-05-29</code>.</p>
<hr />
<h5 id="heading-downloading-and-viewing-files">Downloading and Viewing Files</h5>
<p><code>wget &lt;URL&gt;</code>: Downloads a file from the internet to your current directory.<br /><strong>What Happens</strong>: It fetches the file from the URL and saves it locally with the same name as in the URL.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">wget https://example.com/sample.txt
ls -l
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh   21 May 29 00:43 sample.txt
</code></pre>
<ul>
<li>Assuming <code>sample.txt</code> contains "This is a sample file\n" (21 bytes: 20 characters + newline). If the file already exists, <code>wget</code> might create a new version (e.g., <code>sample.txt.1</code>).</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I might download a script or tool, like <code>wget</code> <a target="_blank" href="https://get.docker.com"><code>https://get.docker.com</code></a> <code>-O</code> <a target="_blank" href="http://docker-install.sh"><code>docker-install.sh</code></a>.</p>
<p><code>curl &lt;URL&gt;</code>: Displays the content of a URL on the terminal (stdout).<br /><strong>What Happens</strong>: It fetches the content and prints it to the screen. To save it, redirect the output with <code>&gt;</code>.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">curl https://example.com/sample.txt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">This is a sample file
</code></pre>
<p><strong>Example (Save Output)</strong>:</p>
<pre><code class="lang-plaintext">curl https://example.com/sample.txt &gt; sample.txt
ls -l
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">-rw-r--r-- 1 suresh suresh   21 May 29 00:43 sample.txt
</code></pre>
<p><strong>Why Useful?</strong>: In DevOps, I might use <code>curl</code> to test an API, like <code>curl</code> <a target="_blank" href="https://api.example.com/status"><code>https://api.example.com/status</code></a>, to check if a service is up.</p>
<p><code>cat &lt;file-name&gt; | grep &lt;word-to-search&gt;</code> or <code>grep &lt;word-to-search&gt; &lt;file&gt;</code>: Searches for a word in a file.<br /><strong>What Happens</strong>: It prints lines from the file that contain the search term. The <code>|</code> (pipe) sends <code>cat</code>’s output to <code>grep</code>.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">echo -e "Hello, DevOps\nLinux is fun\nDevOps rocks" &gt; log.txt
cat log.txt | grep DevOps
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">Hello, DevOps
DevOps rocks
</code></pre>
<p><strong>Alternative</strong>:</p>
<pre><code class="lang-plaintext">grep DevOps log.txt
</code></pre>
<p><strong>Output</strong>: Same as above. Only lines with "DevOps" are shown.</p>
<p><strong>Why Useful?</strong>: In DevOps, I might search logs for errors, like <code>grep "ERROR" /var/log/app.log</code>.</p>
<p><code>tail -f &lt;log-file&gt;</code>: Shows the last lines of a file and updates in real-time as new lines are added.<br /><strong>What Happens</strong>: It displays the last 10 lines by default and keeps showing new lines as they’re written to the file.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">echo "Line 1" &gt; app.log
echo "Line 2" &gt;&gt; app.log
tail -f app.log
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">Line 1
Line 2
</code></pre>
<ul>
<li>If I append to the file in another terminal:</li>
</ul>
<pre><code class="lang-plaintext">echo "Line 3" &gt;&gt; app.log
</code></pre>
<p>The <code>tail -f</code> output updates:</p>
<pre><code class="lang-plaintext">Line 3
</code></pre>
<ul>
<li>Press <code>Ctrl+C</code> to stop.</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I use <code>tail -f</code> to monitor logs in real-time, like <code>tail -f /var/log/nginx/access.log</code> to watch website traffic.</p>
<hr />
<h5 id="heading-extracting-data-from-text">Extracting Data from Text</h5>
<p><code>cut</code>: Extracts parts of text using a delimiter.<br /><strong>What Happens</strong>: It splits each line by the delimiter (<code>-d</code>) and prints the specified field (<code>-f</code>).<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">echo "https://raw.githubusercontent.com/daws-84s/notes/main/session-02.txt" | cut -d "/" -f1
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">https:
</code></pre>
<ul>
<li>The URL is split by <code>/</code>, and the first field (<code>https:</code>) is printed.</li>
</ul>
<p><strong>Example (Third Field)</strong>:</p>
<pre><code class="lang-plaintext">echo "https://raw.githubusercontent.com/daws-84s/notes/main/session-02.txt" | cut -d "/" -f3
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">raw.githubusercontent.com
</code></pre>
<p><strong>Why Useful?</strong>: In DevOps, I might extract parts of log entries, like usernames from a CSV log file.</p>
<p><code>awk</code>: A powerful tool to extract and manipulate text data.<br /><strong>What Happens</strong>: It splits each line by a delimiter (<code>-F</code>) and lets you print specific fields or perform calculations.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">echo "https://raw.githubusercontent.com/daws-84s/notes/main/session-02.txt" | awk -F "/" '{print $1}'
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">https:
</code></pre>
<p><strong>Example (Third Field)</strong>:</p>
<pre><code class="lang-plaintext">echo "https://raw.githubusercontent.com/daws-84s/notes/main/session-02.txt" | awk -F "/" '{print $3}'
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">raw.githubusercontent.com
</code></pre>
<p><strong>Why Useful?</strong>: In DevOps, I might use <code>awk</code> to parse logs, like <code>awk '{print $1}' /var/log/access.log</code> to extract IP addresses from a web server log.</p>
<hr />
<h5 id="heading-finding-files">Finding Files</h5>
<p><code>find &lt;where to search&gt; -name &lt;file-name&gt;</code>: Searches for a file by name in the specified directory and its subdirectories.<br /><strong>What Happens</strong>: It looks recursively for files matching the name and prints their paths.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">mkdir -p /home/suresh/docs
touch /home/suresh/docs/myfile.txt
find /home -name myfile.txt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">/home/suresh/docs/myfile.txt
</code></pre>
<ul>
<li>If the file isn’t found, there’s no output. To search the current directory:</li>
</ul>
<pre><code class="lang-plaintext">cd /home/suresh
find . -name myfile.txt
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">./docs/myfile.txt
</code></pre>
<p><strong>Why Useful?</strong>: In DevOps, I might use <code>find</code> to locate a misplaced config file, like <code>find /etc -name nginx.conf</code>.</p>
<hr />
<h4 id="heading-using-the-vim-editor">Using the <code>vim</code> Editor</h4>
<p><code>vim</code> (Vi Improved) is a powerful text editor in Linux, widely used by DevOps engineers to edit configuration files. It has three modes: Command Mode, Insert Mode, and Last Line Mode (plus a navigation mode often called Normal Mode, entered by pressing <code>Esc</code>).</p>
<h5 id="heading-opening-and-writing-in-vim">Opening and Writing in <code>vim</code></h5>
<p>Run <code>vim &lt;file-name&gt;</code> to open a file.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">vim config.txt
</code></pre>
<p><strong>What Happens</strong>: <code>vim</code> opens <code>config.txt</code>. If the file doesn’t exist, it creates it when you save.</p>
<h5 id="heading-modes-in-vim">Modes in <code>vim</code></h5>
<p><strong>Command Mode (Normal Mode)</strong>: For navigation and quick edits. You start in this mode when you open <code>vim</code>. Press <code>Esc</code> to return to this mode from others.</p>
<ul>
<li><p><code>u</code>: Undo the last change.<br />  <strong>Example</strong>: I type "Line 1", press <code>Esc</code>, type <code>dd</code> (delete line), then <code>u</code>.<br />  <strong>Output</strong>: "Line 1" reappears—deletion is undone.</p>
</li>
<li><p><code>yy</code>: Copy the current line.<br />  <strong>Example</strong>: My file has "Line 1". I move the cursor to that line, type <code>yy</code>, move down, type <code>p</code>.<br />  <strong>Output</strong>:</p>
<pre><code class="lang-plaintext">  Line 1
  Line 1
</code></pre>
</li>
<li><p><code>p</code>: Paste the copied line below the cursor.<br />  <strong>Example</strong>: After <code>yy</code> on "Line 1", I type <code>p</code>. Output is as above.</p>
</li>
<li><p><code>dd</code>: Cut (delete) the current line.<br />  <strong>Example</strong>: My file has:</p>
<pre><code class="lang-plaintext">  Line 1
  Line 2
</code></pre>
<p>  I move to "Line 1", type <code>dd</code>.<br />  <strong>Output</strong>:</p>
<pre><code class="lang-plaintext">  Line 2
</code></pre>
<ul>
<li>"Line 1" is deleted and copied to the clipboard.</li>
</ul>
</li>
<li><p><code>gg</code>: Go to the top of the file.<br />  <strong>Example</strong>: In a 100-line file, I’m at line 50. I type <code>gg</code>.<br />  <strong>Output</strong>: Cursor moves to line 1.</p>
</li>
<li><p><code>Shift+G</code>: Go to the bottom of the file.<br />  <strong>Example</strong>: Same file, I type <code>Shift+G</code>.<br />  <strong>Output</strong>: Cursor moves to line 100.</p>
</li>
</ul>
<p><strong>Insert Mode</strong>: For typing text.</p>
<ul>
<li><p>Press <code>i</code> to enter Insert Mode, type your text, then press <code>Esc</code> to return to Command Mode.<br />  <strong>Example</strong>: I open <code>vim config.txt</code>, press <code>i</code>, type "Listen 80", press <code>Esc</code>, then save (see below).<br />  <strong>Output</strong>: <code>cat config.txt</code> shows:</p>
<pre><code class="lang-plaintext">  Listen 80
</code></pre>
</li>
</ul>
<p><strong>Last Line Mode</strong>: For running commands (like saving or quitting). Enter this mode by typing <code>:</code> in Command Mode.</p>
<ul>
<li><p><code>:q</code>: Quit the file (only works if no changes were made).<br />  <strong>Example</strong>: I open <code>vim config.txt</code>, make no changes, type <code>:q</code>, and press <code>Enter</code>.<br />  <strong>Output</strong>: <code>vim</code> closes, and I’m back at the terminal. If I made changes, I’d get an error: <code>E37: No write since last change</code>.</p>
</li>
<li><p><code>:wq</code>: Save (write) and quit.<br />  <strong>Example</strong>: I type "ServerName <a target="_blank" href="http://localhost">localhost</a>" in <code>config.txt</code>, press <code>Esc</code>, then type <code>:wq</code> and <code>Enter</code>.<br />  <strong>Output</strong>: <code>vim</code> saves the file and exits. <code>cat config.txt</code> shows:</p>
<pre><code class="lang-plaintext">  ServerName localhost
</code></pre>
</li>
<li><p><code>:wq!</code>: Force save and quit (useful if there are permission issues).<br />  <strong>Example</strong>: If <code>config.txt</code> is read-only, <code>:wq</code> might fail, but <code>:wq!</code> forces the save (if I have <code>sudo</code> permissions).<br />  <strong>Output</strong>: File is saved, and <code>vim</code> exits.</p>
</li>
<li><p><code>:q!</code>: Quit without saving.<br />  <strong>Example</strong>: I add "Port 8080" to <code>config.txt</code>, press <code>Esc</code>, then type <code>:q!</code>.<br />  <strong>Output</strong>: <code>vim</code> exits without saving changes. <code>cat config.txt</code> still shows:</p>
<pre><code class="lang-plaintext">  ServerName localhost
</code></pre>
</li>
<li><p><code>:/&lt;word&gt;</code>: Search for a word from the top.<br />  <strong>Example</strong>: In a file with:</p>
<pre><code class="lang-plaintext">  ServerName localhost
  Port 8080
  ServerName example.com
</code></pre>
<p>  I type <code>:/ServerName</code> and press <code>Enter</code>.<br />  <strong>Output</strong>: The cursor jumps to the first "ServerName" (line 1). Press <code>n</code> to jump to the next match (line 3).</p>
</li>
<li><p><code>:?&lt;word&gt;</code>: Search for a word from the bottom.<br />  <strong>Example</strong>: I type <code>:?ServerName</code>.<br />  <strong>Output</strong>: The cursor jumps to the last "ServerName" (line 3). Press <code>n</code> to go to the previous match (line 1).</p>
</li>
<li><p><code>:noh</code>: Removes search highlighting.<br />  <strong>Example</strong>: After searching, matches are highlighted. I type <code>:noh</code>.<br />  <strong>Output</strong>: Highlighting disappears, but I can still press <code>n</code> to jump to matches.</p>
</li>
<li><p><code>:27d</code>: Deletes the 27th line.<br />  <strong>Example</strong>: In a file with 30 lines, I type <code>:27d</code>.<br />  <strong>Output</strong>: Line 27 is deleted; the file now has 29 lines. If there’s no line 27, nothing happens.</p>
</li>
<li><p><code>:%d</code>: Deletes all lines in the file (empties it).<br />  <strong>Example</strong>: My file has:</p>
<pre><code class="lang-plaintext">  Line 1
  Line 2
</code></pre>
<p>  I type <code>:%d</code>.<br />  <strong>Output</strong>: The file is now empty. I save with <code>:wq</code>. <code>cat</code> shows nothing.</p>
</li>
<li><p><code>:3s/sbin/SBIN</code>: In the 3rd line, replaces the first occurrence of "sbin" with "SBIN".<br />  <strong>Example</strong>: My file has:</p>
<pre><code class="lang-plaintext">  Line 1
  Line 2
  sbin is here sbin
</code></pre>
<p>  I type <code>:3s/sbin/SBIN</code>.<br />  <strong>Output</strong>:</p>
<pre><code class="lang-plaintext">  Line 1
  Line 2
  SBIN is here sbin
</code></pre>
<ul>
<li>Only the first "sbin" in line 3 is replaced.</li>
</ul>
</li>
<li><p><code>:3s/sbin/SBIN/g</code>: Replaces all occurrences of "sbin" with "SBIN" in the 3rd line.<br />  <strong>Example</strong>: Same file, I type <code>:3s/sbin/SBIN/g</code>.<br />  <strong>Output</strong>:</p>
<pre><code class="lang-plaintext">  Line 1
  Line 2
  SBIN is here SBIN
</code></pre>
<ul>
<li>Both "sbin"s in line 3 are replaced.</li>
</ul>
</li>
<li><p><code>:%s/sbin/SBIN/g</code>: Replaces all occurrences of "sbin" with "SBIN" in the entire file.<br />  <strong>Example</strong>: My file has:</p>
<pre><code class="lang-plaintext">  sbin on line 1
  Line 2
  sbin is here sbin
</code></pre>
<p>  I type <code>:%s/sbin/SBIN/g</code>.<br />  <strong>Output</strong>:</p>
<pre><code class="lang-plaintext">  SBIN on line 1
  Line 2
  SBIN is here SBIN
</code></pre>
</li>
</ul>
<p><strong>Practical Example with</strong> <code>vim</code>:</p>
<ol>
<li><p>Run <code>vim myfile.txt</code>.</p>
</li>
<li><p>Press <code>i</code>, type:</p>
<pre><code class="lang-plaintext"> ServerName localhost
 Port 8080
 ServerName example.com
</code></pre>
</li>
<li><p>Press <code>Esc</code>, type <code>:/ServerName</code> to search—it jumps to the first "ServerName".</p>
</li>
<li><p>Type <code>:noh</code> to remove highlighting.</p>
</li>
<li><p>Type <code>:%s/ServerName/HostName/g</code> to replace all "ServerName"s with "HostName".<br /> File now looks like:</p>
<pre><code class="lang-plaintext"> HostName localhost
 Port 8080
 HostName example.com
</code></pre>
</li>
<li><p>Type <code>:wq</code> to save and quit.</p>
</li>
</ol>
<p><strong>Why Useful?</strong>: In DevOps, I use <code>vim</code> to edit server configs, like changing a port in <code>/etc/nginx/nginx.conf</code> or updating a script on a remote server.</p>
<hr />
<h4 id="heading-linux-administration-user-management">Linux Administration: User Management</h4>
<p>In DevOps, managing users on a server is crucial, such as creating accounts for team members or removing them when they leave.</p>
<h5 id="heading-crud-operations-for-users">CRUD Operations for Users</h5>
<p><code>useradd &lt;user-name&gt;</code>: Creates a new user.<br /><strong>What Happens</strong>: It adds the user to the system, creates a primary group with the same name as the user, and optionally creates a home directory (with <code>-m</code>).<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">sudo useradd -m suresh
id suresh
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">uid=1001(suresh) gid=1001(suresh) groups=1001(suresh)
</code></pre>
<ul>
<li>A user <code>suresh</code> is created with UID and GID 1001 (numbers may vary). The <code>-m</code> flag ensures the home directory <code>/home/suresh</code> is created. Without <code>-m</code>, the home directory might not be created, depending on the system’s configuration (e.g., <code>/etc/login.defs</code>).</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I create users for team members to access a server.</p>
<p><code>id &lt;user-name&gt;</code>: Shows user details (user ID, group ID, etc.).<br /><strong>What Happens</strong>: It displays the user’s UID, GID, and group memberships.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">id suresh
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">uid=1001(suresh) gid=1001(suresh) groups=1001(suresh)
</code></pre>
<ul>
<li>If the user doesn’t exist:</li>
</ul>
<pre><code class="lang-plaintext">id nosuchuser
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">id: ‘nosuchuser’: no such user
</code></pre>
<p><strong>Why Useful?</strong>: I use <code>id</code> to verify a user was created correctly or to check their group memberships.</p>
<p><code>passwd &lt;user-name&gt;</code>: Sets or changes the user’s password.<br /><strong>What Happens</strong>: It prompts you to enter a new password for the user.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">sudo passwd suresh
</code></pre>
<p><strong>Output (Interaction)</strong>:</p>
<pre><code class="lang-plaintext">Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
</code></pre>
<ul>
<li>I enter a password (e.g., <code>mypassword123</code>). If the passwords don’t match:</li>
</ul>
<pre><code class="lang-plaintext">Sorry, passwords do not match
passwd: Authentication token manipulation error
</code></pre>
<p><strong>Why Useful?</strong>: In DevOps, I set passwords to allow users to log in securely.</p>
<h5 id="heading-managing-groups">Managing Groups</h5>
<p>A group is a collection of users with similar permissions. For example, a DevOps team might have 20 members, so you create a <code>devops</code> group and add them to it.</p>
<p><strong>Primary vs. Secondary Groups</strong>:</p>
<ul>
<li><p>Every user has one primary group (created automatically with the same name as the user).</p>
</li>
<li><p>Users can belong to multiple secondary groups for additional permissions.</p>
</li>
</ul>
<p><code>groupadd &lt;group-name&gt;</code>: Creates a group.<br /><strong>What Happens</strong>: It adds a new group to the system, visible in <code>/etc/group</code>.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">sudo groupadd devops
grep devops /etc/group
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">devops:x:1002:
</code></pre>
<ul>
<li>A group <code>devops</code> is created with GID 1002 (number may vary).</li>
</ul>
<p><strong>Why Useful?</strong>: I create groups to manage permissions for teams, like giving the <code>devops</code> group access to a project folder.</p>
<p><code>usermod -g &lt;group-name&gt; &lt;user-name&gt;</code>: Changes the user’s primary group.<br /><strong>What Happens</strong>: It updates the user’s primary group in <code>/etc/passwd</code>, replacing the previous primary group.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">sudo usermod -g devops suresh
id suresh
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">uid=1001(suresh) gid=1002(devops) groups=1002(devops)
</code></pre>
<ul>
<li><code>suresh</code>’s primary group is now <code>devops</code> (GID 1002).</li>
</ul>
<p><strong>Why Useful?</strong>: I might change a user’s primary group to align with a new team structure.</p>
<p><code>usermod -aG &lt;group-name&gt; &lt;user-name&gt;</code>: Adds the user to a secondary group. The <code>-a</code> (append) flag ensures existing secondary groups aren’t overwritten.<br /><strong>What Happens</strong>: It adds the user to the specified group in <code>/etc/group</code>, keeping other secondary groups intact.<br /><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">sudo groupadd testers
sudo usermod -aG testers suresh
id suresh
</code></pre>
<p><strong>Output</strong>:</p>
<pre><code class="lang-plaintext">uid=1001(suresh) gid=1002(devops) groups=1002(devops),1003(testers)
</code></pre>
<ul>
<li><code>suresh</code> is now in the <code>testers</code> group as a secondary group (GID 1003). Without <code>-a</code>, it would overwrite other secondary groups, a common mistake.</li>
</ul>
<p><strong>Why Useful?</strong>: In DevOps, I add users to secondary groups to grant additional permissions, like access to a testing environment.</p>
<h5 id="heading-removing-a-user-eg-employee-leaving-the-organization">Removing a User (e.g., Employee Leaving the Organization)</h5>
<p>When an employee leaves, you must remove their user account to revoke access. Here’s the standard approach:</p>
<ol>
<li><p><strong>Backup the User’s Data</strong>: Save their files in case they’re needed later.<br /> <strong>Example</strong>:</p>
<pre><code class="lang-plaintext"> sudo cp -r /home/suresh /backups/suresh_backup_$(date +%F)
 ls -l /backups
</code></pre>
<p> <strong>Output</strong>:</p>
<pre><code class="lang-plaintext"> drwxr-xr-x 3 suresh suresh 4096 May 29 00:43 suresh_backup_2025-05-29
</code></pre>
<ul>
<li>This creates <code>/backups/suresh_backup_2025-05-29</code> with all of <code>suresh</code>’s files.</li>
</ul>
</li>
<li><p><strong>Kill the User’s Running Processes</strong>: Ensure the user isn’t running any processes.<br /> <strong>Example</strong>:</p>
<pre><code class="lang-plaintext"> ps -u suresh
</code></pre>
<p> <strong>Output</strong>:</p>
<pre><code class="lang-plaintext">   PID TTY          TIME CMD
  1234 pts/0    00:00:00 bash
  1235 pts/0    00:00:00 vim
</code></pre>
<p> Kill them:</p>
<pre><code class="lang-plaintext"> sudo pkill -u suresh
 ps -u suresh
</code></pre>
<p> <strong>Output</strong>: No processes listed—<code>suresh</code>’s processes are terminated.</p>
</li>
<li><p><strong>Delete the User</strong>: Use <code>userdel</code> to remove the user.</p>
<ul>
<li><p><code>userdel suresh</code>: Removes the user but leaves their home directory.</p>
</li>
<li><p><code>userdel -r suresh</code>: Removes the user and their home directory (including their mail spool).<br />  <strong>Example</strong>:</p>
</li>
</ul>
</li>
</ol>
<pre><code class="lang-plaintext">    sudo userdel -r suresh
    ls -l /home
</code></pre>
<p>    <strong>Output</strong>: <code>/home/suresh</code> is no longer listed—it’s deleted along with the user.</p>
<ol start="4">
<li><p><strong>Verify Removal</strong>: Check if the user is gone.<br /> <strong>Example</strong>:</p>
<pre><code class="lang-plaintext"> id suresh
</code></pre>
<p> <strong>Output</strong>:</p>
<pre><code class="lang-plaintext"> id: ‘suresh’: no such user
</code></pre>
</li>
<li><p><strong>Remove from Groups (Optional)</strong>: Users are automatically removed from groups upon deletion, but I’d verify.<br /> <strong>Example</strong>:</p>
<pre><code class="lang-plaintext"> getent group devops
</code></pre>
<p> <strong>Output</strong>:</p>
<pre><code class="lang-plaintext"> devops:x:1002:
</code></pre>
<ul>
<li><code>suresh</code> is no longer listed in the group.</li>
</ul>
</li>
<li><p><strong>Clean Up (Optional)</strong>: Remove backups after a retention period (e.g., 30 days).<br /> <strong>Example</strong>: After 30 days:</p>
<pre><code class="lang-plaintext"> sudo rm -rf /backups/suresh_backup_2025-05-29
 ls -l /backups
</code></pre>
<p> <strong>Output</strong>: The backup directory is no longer listed.</p>
</li>
</ol>
<p><strong>Why This Approach?</strong>: Backing up data ensures nothing important is lost. Killing processes prevents errors during deletion. Deleting the user and their home directory ensures they can’t access the system, maintaining security. Verifying removal confirms the process worked.</p>
<hr />
<h4 id="heading-why-learn-this-for-devops">Why Learn This for DevOps?</h4>
<p>These Linux skills are crucial for DevOps because:</p>
<ul>
<li><p>You’ll manage servers (e.g., creating files, downloading tools with <code>wget</code>, checking logs with <code>tail</code>).</p>
</li>
<li><p>You’ll edit configuration files (e.g., using <code>vim</code> to update a server config).</p>
</li>
<li><p>You’ll set up team access on servers (e.g., creating users and groups for your DevOps team, or removing users when they leave).</p>
</li>
</ul>
<hr />
<h4 id="heading-interview-questions-for-devops-and-cloud-engineer-roles">Interview Questions for DevOps and Cloud Engineer Roles</h4>
<ol>
<li><p><strong>What are some common</strong> <code>ls</code> command options, and how do they help in DevOps?<br /> <strong>Answer</strong>: The <code>ls</code> command lists files and directories, and its options are useful for DevOps tasks. For example, <code>ls -l</code> gives a long listing with details like permissions, owner, and size—helpful for checking who owns a file on a server. <code>ls -lt</code> sorts by time with the latest files on top, useful for finding recently modified logs or configs. <code>ls -la</code> shows hidden files (like <code>.bashrc</code>), which might contain server settings. In DevOps, I use <code>ls -ltr</code> to see the oldest files at the top when cleaning up old logs, ensuring I don’t delete recent ones.</p>
</li>
<li><p><strong>What’s the difference between</strong> <code>&gt;</code> and <code>&gt;&gt;</code> in Linux, and how would you use them?<br /> <strong>Answer</strong>: The <code>&gt;</code> operator redirects output to a file and overwrites it, while <code>&gt;&gt;</code> appends to the file without overwriting. For example, <code>echo "Hello" &gt; myfile.txt</code> creates <code>myfile.txt</code> with "Hello". Running <code>echo "World" &gt; myfile.txt</code> overwrites it to just "World". But <code>echo "World" &gt;&gt; myfile.txt</code> appends, so the file has:</p>
<pre><code class="lang-plaintext"> Hello
 World
</code></pre>
<p> In DevOps, I might use <code>&gt;</code> to create a new config file (e.g., <code>curl</code> <a target="_blank" href="https://example.com/config"><code>https://example.com/config</code></a> <code>&gt; config.txt</code>) and <code>&gt;&gt;</code> to append logs (e.g., <code>echo "Error occurred" &gt;&gt; error.log</code>).</p>
</li>
<li><p><strong>How does the</strong> <code>vim</code> editor work, and what are some useful commands for a DevOps engineer?<br /> <strong>Answer</strong>: <code>vim</code> has three modes: Command Mode (for navigation), Insert Mode (for typing, entered with <code>i</code>), and Last Line Mode (for commands like saving, entered with <code>:</code>). To edit a file, I run <code>vim config.txt</code>, press <code>i</code> to type changes, press <code>Esc</code> to return to Command Mode, and use <code>:wq</code> to save and quit. Useful commands include <code>:q!</code> to quit without saving, <code>:%s/old/new/g</code> to replace all occurrences of "old" with "new", <code>dd</code> to delete a line, and <code>u</code> to undo. In DevOps, I use <code>vim</code> to edit server configs (e.g., <code>/etc/nginx/nginx.conf</code>). For example, I might use <code>:%s/listen 80/listen 8080/g</code> to change the port number.</p>
</li>
<li><p><strong>How do you create and manage users and groups in Linux? Why is this important for DevOps?</strong><br /> <strong>Answer</strong>: To create a user, I use <code>useradd -m suresh</code> to create the user and their home directory, then <code>passwd suresh</code> to set a password. To create a group, I use <code>groupadd devops</code>. I can change a user’s primary group with <code>usermod -g devops suresh</code> or add them to a secondary group with <code>usermod -aG testers suresh</code>. The <code>-a</code> flag is crucial to append the group without overwriting others. In DevOps, this is vital for managing server access. For example, I might create a <code>devops</code> group for my team, add members to it, and set permissions so only they can access certain project folders, ensuring security and collaboration.</p>
</li>
<li><p><strong>What’s the difference between</strong> <code>wget</code> and <code>curl</code>, and how would you use them in a DevOps task?<br /> <strong>Answer</strong>: <code>wget</code> downloads a file directly to your directory, while <code>curl</code> displays the content on the screen unless redirected. For example, <code>wget</code> <a target="_blank" href="https://example.com/script.sh"><code>https://example.com/script.sh</code></a> downloads <a target="_blank" href="http://script.sh"><code>script.sh</code></a>, but <code>curl</code> <a target="_blank" href="https://example.com/script.sh"><code>https://example.com/script.sh</code></a> shows its content. To save with <code>curl</code>, I’d use <code>curl</code> <a target="_blank" href="https://example.com/script.sh"><code>https://example.com/script.sh</code></a> <code>&gt;</code> <a target="_blank" href="http://script.sh"><code>script.sh</code></a>. In DevOps, I might use <code>wget</code> to download a tool (e.g., <code>wget</code> <a target="_blank" href="https://get.docker.com"><code>https://get.docker.com</code></a> <code>-O</code> <a target="_blank" href="http://docker-install.sh"><code>docker-install.sh</code></a>) or <code>curl</code> to check an API response (e.g., <code>curl</code> <a target="_blank" href="https://api.example.com/status"><code>https://api.example.com/status</code></a>) while troubleshooting a server issue.</p>
</li>
<li><p><strong>How do you search for a file or text in Linux, and why is this useful in DevOps?</strong><br /> <strong>Answer</strong>: To search for a file, I use <code>find /path -name filename</code>, like <code>find /home -name config.txt</code>. To search for text in a file, I use <code>grep</code>, like <code>grep "error" logfile.txt</code>. I can also combine commands, such as <code>tail -f /var/log/app.log | grep "exception"</code> to monitor logs in real-time for errors. In DevOps, this is useful for debugging. For example, I might use <code>find /etc -name nginx.conf</code> to locate a config file I need to edit.</p>
</li>
<li><p><strong>What are primary and secondary groups in Linux, and how do you assign them to a user?</strong><br /> <strong>Answer</strong>: Every user has one primary group, created with the same name as the user during <code>useradd</code>. They can also belong to multiple secondary groups for additional permissions. For example, <code>useradd suresh</code> creates a user and a primary group <code>suresh</code>. To change the primary group, I use <code>usermod -g devops suresh</code>. To add a secondary group, I use <code>usermod -aG testers suresh</code>. In DevOps, this helps manage permissions—for example, I might add all developers to a <code>dev</code> group to give them access to a project directory.</p>
</li>
<li><p><strong>How do you remove a user in Linux when an employee leaves an organization, and what is the standard approach?</strong><br /> <strong>Answer</strong>: I follow a standard approach to remove a user securely. First, I back up their data with <code>cp -r /home/suresh /backups/suresh_backup_$(date +%F)</code>. Second, I kill their processes with <code>pkill -u suresh</code>. Third, I delete the user with <code>userdel -r suresh</code>, which removes the user and their home directory. Fourth, I verify removal with <code>id suresh</code> (should return "no such user"). Finally, I check group memberships with <code>getent group devops</code> and may clean up backups after 30 days. This ensures security, preserves data if needed, and confirms complete removal.</p>
</li>
<li><p><strong>How do you manage file permissions in Linux, and why is this important for a DevOps engineer?</strong><br /> <strong>Answer</strong>: File permissions are managed with <code>chmod</code> and <code>chown</code>. Permissions are in three parts: owner, group, and others, with read (4), write (2), and execute (1) permissions. For example, <code>chmod 644 myfile.txt</code> gives the owner read/write (6) and others read-only (4). <code>chown suresh:devops myfile.txt</code> sets <code>suresh</code> as the owner and <code>devops</code> as the group. In DevOps, this is critical for security. For example, I might set <code>chmod 600 ssh_key.pem</code> to ensure only the owner can access an SSH key, preventing unauthorized access to a server.</p>
</li>
<li><p><strong>What is SSH, and how would you use it to access a remote server in a DevOps role?</strong><br /><strong>Answer</strong>: SSH (Secure Shell) is a protocol to securely access a remote server. I use <code>ssh user@hostname</code> to connect. For example, <code>ssh suresh@192.168.1.100</code> logs me into the server at <code>192.168.1.100</code> as <code>suresh</code>. If I have a private key, I use <code>ssh -i ssh_key.pem suresh@192.168.1.100</code>. In DevOps, SSH is used to manage servers—for example, I might SSH into an AWS EC2 instance to check logs, restart a service, or deploy an application.</p>
</li>
<li><p><strong>What are some basic cloud concepts a DevOps engineer should know, and how do they relate to Linux?</strong><br /><strong>Answer</strong>: DevOps engineers often work with cloud platforms like AWS, Azure, or GCP. Key concepts include virtual machines (like AWS EC2, which often run Linux), storage (like AWS S3), and networking (like VPCs). For example, I might launch an EC2 instance running Ubuntu, SSH into it, and install an application. Linux skills are crucial because most cloud servers run Linux. I’d use <code>wget</code> to download a package, <code>vim</code> to edit configs, and <code>systemctl</code> to manage services on the cloud server, ensuring the application runs smoothly.</p>
</li>
</ol>
<hr />
]]></content:encoded></item><item><title><![CDATA[Introduction to DevOps for Beginners]]></title><description><![CDATA[What is DevOps?
DevOps is a way to make software development and delivery faster, better, and more reliable. It’s about bringing the development team (who writes the code) and the operations team (who manages the servers and deployment) together to w...]]></description><link>https://intro-to-devops-legacy-to-modern.hashnode.dev/introduction-to-devops-for-beginners</link><guid isPermaLink="true">https://intro-to-devops-legacy-to-modern.hashnode.dev/introduction-to-devops-for-beginners</guid><category><![CDATA[devops-beginners]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[automation]]></category><dc:creator><![CDATA[ESHNITHIN YADAV]]></dc:creator><pubDate>Wed, 30 Apr 2025 18:30:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-what-is-devops">What is DevOps?</h2>
<p>DevOps is a way to make software development and delivery faster, better, and more reliable. It’s about bringing the development team (who writes the code) and the operations team (who manages the servers and deployment) together to work as one team. The goal of DevOps is to build, test, and deploy code on the same day it’s written, instead of waiting until the end of a long project. This reduces defects (errors in the code) and makes the software ready for users quickly.</p>
<p>For example, imagine you’re building a school management system with features like login, signup, and exam results. In the past, developers would take months to build everything, and only at the end would they test and deploy it. If there were 100 defects, fixing them would take a lot of time. With DevOps, you test and deploy small parts (like the login feature) on the same day they’re built, so you catch and fix defects early—maybe only 10 defects instead of 100.</p>
<h2 id="heading-why-do-we-need-devops-understanding-the-software-development-lifecycle-sdlc">Why Do We Need DevOps? Understanding the Software Development Lifecycle (SDLC)</h2>
<p>The SDLC is the process of creating software, step by step. It includes:</p>
<ol>
<li><p><strong>Requirements Analysis</strong>: Gathering what the client needs (e.g., a login system for students).</p>
</li>
<li><p><strong>Planning</strong>: Deciding how to build it.</p>
</li>
<li><p><strong>Design</strong>: Turning general ideas into technical plans.</p>
</li>
<li><p><strong>Implementation</strong>: Writing the code.</p>
</li>
<li><p><strong>Testing</strong>: Checking if the code works properly.</p>
</li>
<li><p><strong>Deployment</strong>: Releasing the code to users.</p>
</li>
<li><p><strong>Maintenance</strong>: Fixing issues and adding new features.</p>
</li>
</ol>
<h3 id="heading-old-way-waterfall-model">Old Way: Waterfall Model</h3>
<p>50 years ago, software was built using the Waterfall model. This was like a strict, step-by-step process:</p>
<ul>
<li><p>Finish one step (like requirements) before moving to the next.</p>
</li>
<li><p>You can’t change requirements once they’re set.</p>
</li>
<li><p>For a 2-year project, deployment happens only at the end. If there are 100 defects, fixing them takes a lot of time.</p>
</li>
</ul>
<p>This was slow and risky because defects were found too late. It’s like studying for an exam only at the end of the year—you might fail because you didn’t practice earlier.</p>
<h3 id="heading-better-way-agile">Better Way: Agile</h3>
<p>Agile improved on Waterfall by breaking the project into smaller parts called "sprints" (usually 30 days each). For example:</p>
<ul>
<li><p>Sprint 1: Build and test the login and signup features.</p>
</li>
<li><p>Sprint 2: Build and test the orders feature.</p>
</li>
</ul>
<p>In Agile, you test and deploy after each sprint, so defects are found earlier. If a sprint has 5 defects, you fix them before moving to the next sprint. Agile also includes daily meetings (called standups) to keep everyone on track.</p>
<h3 id="heading-best-way-devops">Best Way: DevOps</h3>
<p>DevOps takes Agile further by making the process even faster and more automated. Instead of waiting 30 days for a sprint, you build, test, and deploy on the same day. For example:</p>
<ul>
<li><p>Day 1: Write code for the login feature (e.g., entering first name, last name, and date of birth).</p>
</li>
<li><p>Day 1: Test it and deploy it to a server for users to try.</p>
</li>
<li><p>Result: If there are 10 defects, you fix them immediately.</p>
</li>
</ul>
<p>DevOps uses practices like:</p>
<ul>
<li><p><strong>Automation</strong>: Using tools to automatically test and deploy code.</p>
</li>
<li><p><strong>Continuous Integration (CI)</strong>: Developers regularly merge their code into a shared system, and it’s automatically-tested.</p>
</li>
<li><p><strong>Continuous Deployment (CD)</strong>: Code that passes tests is automatically deployed to production.</p>
</li>
<li><p><strong>Continuous Testing</strong>: Testing happens all the time, not just at the end.</p>
</li>
<li><p><strong>Continuous Monitoring</strong>: Watching the system to catch issues early.</p>
</li>
</ul>
<p>This means fewer defects, faster releases, and happier users.</p>
<h2 id="heading-devops-in-action-a-school-example">DevOps in Action: A School Example</h2>
<p>Think of DevOps like studying smarter for school exams. 50 years ago, students took one big exam at the end of the year (like Waterfall). If they failed, it was too late to improve. Then, schools added more exams throughout the year—unit tests, quarterly exams, and half-yearly exams (like Agile). This helped students improve step by step. Now, imagine daily "slip tests" where students are tested every day, get feedback, and improve immediately (like DevOps). With daily slip tests, students, teachers, and parents stay serious, and the pass percentage goes up to 99%!</p>
<h2 id="heading-devops-vs-other-models">DevOps vs. Other Models</h2>
<ul>
<li><p><strong>Waterfall</strong>: Slow, rigid, defects found late.</p>
</li>
<li><p><strong>Agile</strong>: Faster, sprints of 30 days, defects found earlier.</p>
</li>
<li><p><strong>DevOps</strong>: Fastest, same-day deployment, very few defects.</p>
</li>
<li><p><strong>DevSecOps</strong>: DevOps with a focus on security (e.g., checking for vulnerabilities).</p>
</li>
<li><p><strong>AIOps</strong>: DevOps with artificial intelligence to predict and fix issues automatically.</p>
</li>
</ul>
<h2 id="heading-why-use-linux-in-devops">Why Use Linux in DevOps?</h2>
<p>Many DevOps tools run on Linux because:</p>
<ul>
<li><p>It’s free and open-source (unlike Windows, which is costly).</p>
</li>
<li><p>It’s secure (no need for antivirus).<br />  tannus- It’s fast and uses fewer resources (only 9MB for the basic system).</p>
</li>
<li><p>It’s easy to update and install packages.</p>
</li>
<li><p>It was created by Linus Torvalds, who also invented Git (a tool used in DevOps to manage code).</p>
</li>
</ul>
<h2 id="heading-key-environments-in-devops">Key Environments in DevOps</h2>
<p>When building software, it goes through stages:</p>
<ul>
<li><p><strong>DEV</strong>: Where developers write code.</p>
</li>
<li><p><strong>QA</strong>: Quality assurance (testing for bugs).</p>
</li>
<li><p><strong>SIT</strong>: System integration testing (checking if all parts work together).</p>
</li>
<li><p><strong>UAT</strong>: User acceptance testing (clients test the software).</p>
</li>
<li><p><strong>PERF</strong>: Performance testing (checking speed and scalability).</p>
</li>
<li><p><strong>PRE-PROD</strong>: A test environment that mimics production.</p>
</li>
<li><p><strong>PROD</strong>: The live environment where end users access the software.</p>
</li>
</ul>
<h2 id="heading-devops-qas-important-for-interviews">DevOps Q/A’s Important for Interviews?</h2>
<p>In an interview, you might be asked the following questions about DevOps. Here are the questions along with detailed answers to help you prepare:</p>
<ul>
<li><p><strong>What is DevOps?</strong><br />  <strong>Answer</strong>: DevOps is a set of practices that brings the development and operations teams together to work as one. It focuses on building, testing, and deploying code on the same day it’s written, instead of waiting until the end of a project. For example, if I write a login feature today, I test and deploy it today itself using DevOps practices like automation, continuous integration (CI), continuous deployment (CD), and continuous testing. This reduces defects and speeds up software delivery. DevOps is all about collaboration, automation, and delivering high-quality software faster.</p>
</li>
<li><p><strong>How is DevOps different from Agile?</strong><br />  <strong>Answer</strong>: Agile is a development methodology that breaks a project into smaller parts called sprints, typically 30 days long. In Agile, you build, test, and deploy after each sprint, which means you might wait 30 days to release a feature. DevOps, on the other hand, takes Agile further by enabling daily deployments. With DevOps, I can build a feature, test it, and deploy it on the same day using automation tools. For example, in Agile, I might finish a login feature in 30 days with 5 defects, but in DevOps, I deploy the login feature on Day 1 with maybe 1 defect because I test and fix issues immediately. DevOps also focuses more on automation and collaboration between development and operations teams.</p>
</li>
<li><p><strong>Why use Linux in DevOps?</strong><br />  <strong>Answer</strong>: Linux is widely used in DevOps because it’s free, open-source, secure, and efficient. Unlike Windows, which is costly and requires antivirus software, Linux is secure by design and doesn’t need antivirus. It’s also very lightweight—Linux only needs 9MB of space for its basic system, so it runs faster and uses fewer resources. Linux is fast because it’s mostly text-based, unlike Windows, which has heavy graphics. Treasures. It’s also easy to update or install new packages on Linux, and it rarely needs restarts, unlike Windows, which often requires frequent reboots. Plus, Linux was created by Linus Torvalds, who also invented Git, a tool we use in DevOps to manage code. All these reasons make Linux a top choice for DevOps environments.</p>
</li>
<li><p><strong>What are the benefits of DevOps?</strong><br />  <strong>Answer</strong>: DevOps offers several key benefits that make software development better. First, it allows for faster releases—since we build, test, and deploy code on the same day, features reach users much quicker than in traditional methods like Waterfall, where deployment might take months or years. Second, DevOps leads to fewer defects because we test continuously and catch issues early; for example, instead of finding 100 defects at the end of a project, we might only have 10 defects by fixing them daily. Third, it improves teamwork by bringing developers and operations teams together, so they collaborate better and solve problems as a unit. Finally, DevOps makes users happier because they get high-quality software faster, with fewer bugs, and the software can be updated more frequently with new features. Overall, DevOps makes the entire process more efficient and reliable.</p>
</li>
</ul>
<p>DevOps is all about automation and speed, making software delivery efficient and reliable!  </p>
<p>Thank You.</p>
]]></content:encoded></item></channel></rss>