<?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: Nagesh K</title>
    <description>The latest articles on DEV Community by Nagesh K (@nagesh_k_2003).</description>
    <link>https://dev.to/nagesh_k_2003</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%2F3836640%2F5bdc2022-954d-45ba-8a40-dedd87d26ee5.png</url>
      <title>DEV Community: Nagesh K</title>
      <link>https://dev.to/nagesh_k_2003</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nagesh_k_2003"/>
    <language>en</language>
    <item>
      <title>🔥 Automating Linux Tasks: Cron Jobs + Logging</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Tue, 07 Apr 2026 07:42:22 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/devops-upgrade-cron-jobs-with-logging-26pa</link>
      <guid>https://dev.to/nagesh_k_2003/devops-upgrade-cron-jobs-with-logging-26pa</guid>
      <description>&lt;p&gt;Automation is the backbone of DevOps, and cron jobs are one of the simplest yet most powerful tools for scheduling repetitive tasks in Linux. But here’s the golden rule : Never run cron without logs.&lt;br&gt;
Without logs, you’re flying blind — you won’t know if your job succeeded, failed, or silently broke.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🕒 What is a Cron Job?&lt;/strong&gt;&lt;br&gt;
Cron is a time-based job scheduler in Unix/Linux.&lt;br&gt;
It runs commands or scripts at specified intervals (minutes, hours, days).&lt;br&gt;
Perfect for tasks like backups, monitoring, cleanup, or reporting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Example: Disk Usage Monitoring with Logging&lt;/strong&gt;&lt;br&gt;
Here’s a production-ready cron job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/5 * * * * /home/ubuntu/disk.sh &amp;gt;&amp;gt; /home/ubuntu/disk.log 2&amp;gt;&amp;amp;1
*/5 * * * * → Run every 5 minutes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/home/ubuntu/disk.sh&lt;/code&gt; → Script to check disk usage&lt;br&gt;
&lt;code&gt;&amp;gt;&amp;gt; /home/ubuntu/disk.log&lt;/code&gt; → Append standard output to log file&lt;br&gt;
&lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; → Redirect errors to the same log file&lt;br&gt;
👉 This ensures both success and failure messages are captured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛡️ Why Logging Matters&lt;/strong&gt;&lt;br&gt;
Observability → Know what happened at each run.&lt;br&gt;
Debugging → Errors are visible in logs.&lt;br&gt;
Auditing → Historical record of job execution.&lt;br&gt;
Reliability → Prevents silent failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚡ Common Mistake: Typo in Service Name&lt;/strong&gt;&lt;br&gt;
A real-world example you might encounter:&lt;br&gt;
&lt;code&gt;ubuntu@ip-172-31-39-174:~/shell-script-learnings$ sudo systemctl stop corn&lt;br&gt;
Failed to stop corn.service: Unit corn.service not loaded.&lt;/code&gt;&lt;br&gt;
👉 The error happened because the service name is cron, not corn.&lt;br&gt;
Correct command:&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;sudo &lt;/span&gt;systemctl stop cron
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start cron
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status cron
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📝 Managing Cron Jobs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Add a Cron Job&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;crontab -e&lt;/code&gt; : Paste your job line, save, and exit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. List Current Cron Jobs&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;crontab -l&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Remove a Specific Cron Job&lt;/strong&gt;&lt;br&gt;
Open crontab: &lt;code&gt;crontab -e&lt;/code&gt;&lt;br&gt;
Delete the line corresponding to the job, Save and exit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Delete All Cron Jobs&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;crontab -r&lt;/code&gt;&lt;br&gt;
⚠️ This wipes the entire crontab for the user.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 Production Enhancements
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Timestamps in logs:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;*/5 * * * * echo "$(date) - Running disk.sh" &amp;gt;&amp;gt; /home/ubuntu/disk.log 2&amp;gt;&amp;amp;1; /home/ubuntu/disk.sh &amp;gt;&amp;gt; /home/ubuntu/disk.log 2&amp;gt;&amp;amp;1&lt;/code&gt;&lt;br&gt;
Log rotation (prevent infinite growth):&lt;br&gt;
Create /etc/logrotate.d/disk:&lt;br&gt;
Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;/&lt;span class="n"&gt;home&lt;/span&gt;/&lt;span class="n"&gt;ubuntu&lt;/span&gt;/&lt;span class="n"&gt;disk&lt;/span&gt;.&lt;span class="n"&gt;log&lt;/span&gt; {
    &lt;span class="n"&gt;daily&lt;/span&gt;
    &lt;span class="n"&gt;rotate&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
    &lt;span class="n"&gt;compress&lt;/span&gt;
    &lt;span class="n"&gt;missingok&lt;/span&gt;
    &lt;span class="n"&gt;notifempty&lt;/span&gt;
    &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="m"&gt;644&lt;/span&gt; &lt;span class="n"&gt;ubuntu&lt;/span&gt; &lt;span class="n"&gt;ubuntu&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🎯 Conclusion&lt;/strong&gt;&lt;br&gt;
Cron jobs are deceptively simple but incredibly powerful. The difference between a hobby script and a production-grade job is logging and management.&lt;br&gt;
Always log output and errors.&lt;br&gt;
Monitor logs with rotation.&lt;br&gt;
Manage jobs cleanly with crontab -e, crontab -l, and crontab -r.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>shell</category>
      <category>devops</category>
      <category>automation</category>
    </item>
    <item>
      <title>Understanding Script vs Function Arguments in Bash</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Fri, 03 Apr 2026 04:07:08 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/understanding-script-vs-function-arguments-in-bash-3l9p</link>
      <guid>https://dev.to/nagesh_k_2003/understanding-script-vs-function-arguments-in-bash-3l9p</guid>
      <description>&lt;p&gt;When writing shell scripts, one of the most common sources of confusion is positional parameters — the $1, $2, $3 variables that represent arguments passed to a script or function. Let’s walk through a real example to make this crystal clear.&lt;/p&gt;

&lt;p&gt;The Script:&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;#!/bin/bash&lt;/span&gt;

backup&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="nv"&gt;backup_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%F_%H-%M-%S&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-czf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$backup_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&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;"✅ Backup created: &lt;/span&gt;&lt;span class="nv"&gt;$backup_name&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;"❌ Backup failed for &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

list&lt;span class="o"&gt;(){&lt;/span&gt;
    find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.tar.gz"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt; &lt;span class="k"&gt;in
    &lt;/span&gt;back&lt;span class="p"&gt;)&lt;/span&gt;
        backup &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
    list&lt;span class="p"&gt;)&lt;/span&gt;
        list
        &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage:"&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;$0&lt;/span&gt;&lt;span class="s2"&gt; back &amp;lt;directory_or_file&amp;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;$0&lt;/span&gt;&lt;span class="s2"&gt; list"&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;How It Works&lt;br&gt;
Step 1: Script Arguments&lt;br&gt;
When you run:&lt;br&gt;
&lt;code&gt;./backup-manager.sh back dir21&lt;/code&gt;&lt;br&gt;
$0 → ./backup-manager.sh (the script name)&lt;br&gt;
$1 → back&lt;br&gt;
$2 → dir21&lt;br&gt;
The case statement checks $1. Since it’s back, the script calls:&lt;br&gt;
&lt;code&gt;backup "$2"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Step 2: Function Arguments&lt;br&gt;
Now the function backup() is called with one argument: dir21.&lt;br&gt;
Inside the function:&lt;br&gt;
$1 → dir21 (because $1 inside a function refers to the first argument passed to that function, not the script’s $1 anymore).&lt;br&gt;
That’s why you see $2 in the script but $1 inside the function — they’re different scopes.&lt;/p&gt;

&lt;p&gt;Example Run&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ ./backup-manager.sh back dir21&lt;/code&gt;&lt;br&gt;
✅ Backup created: dir21_2026-04-03_09-25-00.tar.gz&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ ./backup-manager.sh list&lt;/code&gt;&lt;br&gt;
./dir21_2026-04-03_09-25-00.tar.gz&lt;br&gt;
Key Takeaways&lt;br&gt;
Script arguments ($1, $2, …) are what the user types after the script name.&lt;br&gt;
Function arguments ($1, $2, … inside the function) are what you pass when calling the function.&lt;br&gt;
They are independent: $1 in the script is not the same as $1 inside the function.&lt;/p&gt;

&lt;p&gt;Bonus Tip: Multiple Backups&lt;br&gt;
You can extend the script to back up multiple directories at once:&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="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt; &lt;span class="k"&gt;in
    &lt;/span&gt;back&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;shift&lt;/span&gt;   &lt;span class="c"&gt;# remove "back" from arguments&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;target &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&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;backup &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$target&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;done&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
    list&lt;span class="p"&gt;)&lt;/span&gt;
        list
        &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; back &amp;lt;dir1&amp;gt; &amp;lt;dir2&amp;gt; ... | &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; list"&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run: &lt;code&gt;./backup-manager.sh back dir21 dir22 dir23&lt;/code&gt;&lt;br&gt;
and it will back up all three.&lt;/p&gt;

&lt;p&gt;💡 This is a great example to blog about because it shows the layered nature of arguments in Bash — script level vs function level — and clears up a common beginner confusion.&lt;/p&gt;

</description>
      <category>bash</category>
      <category>shell</category>
      <category>linux</category>
    </item>
    <item>
      <title>Git Push Rejected: Understanding and Fixing Common Errors</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Thu, 02 Apr 2026 14:21:02 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/git-push-rejected-understanding-and-fixing-common-errors-41mb</link>
      <guid>https://dev.to/nagesh_k_2003/git-push-rejected-understanding-and-fixing-common-errors-41mb</guid>
      <description>&lt;p&gt;When working with Git, one of the most common frustrations developers face is the dreaded push rejected error. This usually happens when your local branch is out of sync with the remote branch. Let’s break down why this occurs and how to fix it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Does Git Reject a Push?&lt;/strong&gt;&lt;br&gt;
Git prevents you from overwriting changes that exist on the remote but not in your local branch. This ensures that you don’t accidentally erase someone else’s work or lose commits. The error message often looks like this:&lt;/p&gt;

&lt;p&gt;! [rejected]        main -&amp;gt; main (fetch first)&lt;br&gt;
error: failed to push some refs to '&lt;a href="https://github.com/.." rel="noopener noreferrer"&gt;https://github.com/..&lt;/a&gt;.'&lt;br&gt;
hint: Updates were rejected because the remote contains work that you do not&lt;br&gt;
hint: have locally.&lt;/p&gt;

&lt;p&gt;Common Fixes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Rebase (Recommended)&lt;/strong&gt; : If you want to keep a clean, linear history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git pull origin main &lt;span class="nt"&gt;--rebase&lt;/span&gt;
&lt;span class="c"&gt;# resolve conflicts if any&lt;/span&gt;
git rebase &lt;span class="nt"&gt;--continue&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach reapplies your local commits on top of the remote branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Merge&lt;/strong&gt; : If you don’t mind merge commits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git pull origin main
&lt;span class="c"&gt;# resolve conflicts if any&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a merge commit combining both histories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Force Push (Dangerous)&lt;/strong&gt; : If you want to overwrite the remote branch entirely:&lt;br&gt;
&lt;code&gt;git push origin main --force&lt;/code&gt;&lt;br&gt;
⚠️ Warning: This will erase remote commits not present locally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What About &lt;code&gt;--allow-unrelated-histories&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
This option is used when two repositories don’t share a common history (e.g., you initialized locally and then connected to a remote with its own commits). It forces Git to merge unrelated histories. In most cases, you don’t need this if your local and remote already share a history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices:&lt;/strong&gt; &lt;br&gt;
Use rebase for a clean history.&lt;br&gt;
Use merge if you prefer explicit merge commits.&lt;br&gt;
Avoid force push unless you’re absolutely sure.&lt;br&gt;
Reserve --allow-unrelated-histories for truly separate repositories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
A rejected push isn’t a blocker—it’s Git protecting your project’s history. By understanding when to rebase, merge, or force push, you can resolve these errors confidently and keep your repository healthy.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
    </item>
    <item>
      <title>Git Clone vs Remote Add: The Battle of First Steps</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Wed, 25 Mar 2026 03:23:28 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/git-clone-vs-remote-add-the-battle-of-first-steps-4a0k</link>
      <guid>https://dev.to/nagesh_k_2003/git-clone-vs-remote-add-the-battle-of-first-steps-4a0k</guid>
      <description>&lt;p&gt;When you’re new to Git, one of the most confusing questions is:&lt;br&gt;
Should I use git clone or git remote add origin … + git pull?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s make this fun and crystal clear.&lt;br&gt;
🖥️ git clone:&lt;/strong&gt; The One-Click Magic&lt;br&gt;
Think of git clone as the “Download Project” button.&lt;/p&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;code&gt;git clone https://github.com/company/project.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Git does all the heavy lifting for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a new folder named project.&lt;/li&gt;
&lt;li&gt;Runs git init inside it.&lt;/li&gt;
&lt;li&gt;Connects the remote (origin).&lt;/li&gt;
&lt;li&gt;Pulls down all files + commit history.
👉 In one shot, you have a fully working project folder ready to explore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📂 git remote add origin … + git pull: The Manual Way&lt;/strong&gt;&lt;br&gt;
This is more like building your own workspace from scratch.&lt;/p&gt;

&lt;p&gt;Steps 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;&lt;span class="nb"&gt;mkdir &lt;/span&gt;myrepo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;myrepo
git init
git remote add origin https://github.com/company/project.git
git pull origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the folder yourself.&lt;/li&gt;
&lt;li&gt;Initialize Git manually.&lt;/li&gt;
&lt;li&gt;Tell Git where the remote is.&lt;/li&gt;
&lt;li&gt;Finally, pull the files.
👉 It works, but it’s extra steps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🎯 The Shortcut vs The Long Road&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;git clone → Best when you just want the project as-is. Quick, clean, automatic.&lt;/li&gt;
&lt;li&gt;remote add + pull → Best when you already created a repo locally and now want to connect it to a remote.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;💡 Imagine it like this:&lt;/strong&gt;&lt;br&gt;
Clone = “Download the whole project in one click.”&lt;br&gt;
Remote add + pull = “I made an empty folder, now let me link it and fetch files.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Bottom Line&lt;/strong&gt;&lt;br&gt;
If you’re a new user who wants the same project folder from GitHub, always use git clone.&lt;br&gt;
The manual method is only for special cases when you’ve already set up a repo locally.&lt;/p&gt;

&lt;p&gt;🔥 Next time you see a cool project online, just remember:&lt;br&gt;
Clone it, don’t complicate it.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>devops</category>
    </item>
    <item>
      <title>Day -2 : Essential Linux File System Knowledge for DevOps Engineers.</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Mon, 23 Mar 2026 16:20:56 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/day-2-essential-linux-file-system-knowledge-for-devops-engineers-m4l</link>
      <guid>https://dev.to/nagesh_k_2003/day-2-essential-linux-file-system-knowledge-for-devops-engineers-m4l</guid>
      <description>&lt;p&gt;As a DevOps engineer, understanding the Linux file system is non‑negotiable. It’s the foundation of where you store code, configure services, check logs, and deploy applications. In this post, I’ll walk you through the most important directories, their purposes, and how you should use them in daily DevOps work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏠 User Workspaces vs System Areas&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User workspace (/home/): This is where you should keep your project code, scripts, and personal files. For example, if your username is ubuntu, your workspace is /home/ubuntu.&lt;/li&gt;
&lt;li&gt;System areas (/etc, /var, /usr, etc.): These directories are reserved for configurations, logs, binaries, and deployments. You’ll often need sudo to work here because they affect the whole system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📂 Key Directories Every DevOps Engineer Must Know&lt;/strong&gt;&lt;br&gt;
/home/&lt;br&gt;
Purpose: User’s personal workspace&lt;br&gt;
DevOps Usage: Store project code, scripts, configs&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;cd ~&lt;br&gt;
cd /home/ubuntu&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/root&lt;br&gt;
Purpose: Root user’s home directory&lt;br&gt;
DevOps Usage: Reserved for admin tasks, not coding&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;sudo su -&lt;br&gt;
cd /root&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/etc&lt;br&gt;
Purpose: System configuration files&lt;br&gt;
DevOps Usage: Manage service configs (Nginx, SSH, systemd)&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;cd /etc/nginx&lt;br&gt;
nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/var/log&lt;br&gt;
Purpose: System and application logs&lt;br&gt;
DevOps Usage: Debug services, monitor errors&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;tail -f /var/log/syslog&lt;br&gt;
less /var/log/nginx/error.log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/var/www&lt;br&gt;
Purpose: Web server files&lt;br&gt;
DevOps Usage: Deploy websites and applications&lt;br&gt;
Example Commands:&lt;br&gt;
cd /var/www/html&lt;br&gt;
git clone &lt;/p&gt;

&lt;p&gt;/usr/bin&lt;br&gt;
Purpose: User binaries (commands available to all users)&lt;br&gt;
DevOps Usage: Run system commands like ls, grep, etc.&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;ls /usr/bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/bin&lt;br&gt;
Purpose: Essential binaries for boot and recovery&lt;br&gt;
DevOps Usage: Core commands like cat, cp, mv&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;ls /bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/sbin&lt;br&gt;
Purpose: System binaries for admin tasks&lt;br&gt;
DevOps Usage: Commands like shutdown, mount&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;ls /sbin&lt;br&gt;
shutdown -h now&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/opt&lt;br&gt;
Purpose: Optional software packages&lt;br&gt;
DevOps Usage: Install custom tools or third‑party apps&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;cd /opt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/tmp&lt;br&gt;
Purpose: Temporary files (cleared on reboot)&lt;br&gt;
DevOps Usage: Scratch space for testing or temporary storage&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;cd /tmp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/dev&lt;br&gt;
Purpose: Device files&lt;br&gt;
DevOps Usage: Interfaces to hardware (disks, terminals)&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;ls /dev/sda&lt;br&gt;
ls /dev/tty&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/proc&lt;br&gt;
Purpose: Virtual filesystem with process and kernel info&lt;br&gt;
DevOps Usage: Check CPU, memory, and process details&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;cat /proc/cpuinfo&lt;br&gt;
cat /proc/meminfo&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/mnt and /media&lt;br&gt;
Purpose: Mount points for external drives&lt;br&gt;
DevOps Usage: Access USBs, external disks&lt;br&gt;
Example Commands:&lt;br&gt;
&lt;code&gt;cd /mnt&lt;br&gt;
ls /media/ubuntu&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One‑liners for each directory (quick reference).&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;/home → user workspace&lt;br&gt;
/root → root’s home&lt;br&gt;
/etc → configs&lt;br&gt;
/var/log → logs&lt;br&gt;
/var/www → web apps&lt;br&gt;
/usr/bin → user binaries&lt;br&gt;
/bin → essential binaries&lt;br&gt;
/sbin → admin binaries&lt;br&gt;
/opt → optional software&lt;br&gt;
/tmp → temporary files&lt;br&gt;
/dev → devices&lt;br&gt;
/proc → process info&lt;br&gt;
/mnt,/media → mount points&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Best Practices for DevOps Work
&lt;/h2&gt;

&lt;p&gt;Workspace: Keep your project repos inside /home/ubuntu.&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;mkdir myproject &amp;amp;&amp;amp; cd myproject &amp;amp;&amp;amp; git init&lt;/code&gt;&lt;br&gt;
System Configs: Edit service configs in &lt;code&gt;/etc&lt;/code&gt; using sudo.&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;sudo nano /etc/nginx/nginx.conf&lt;/code&gt;&lt;br&gt;
Logs: Monitor logs in &lt;code&gt;/var/log&lt;/code&gt; for debugging.&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;tail -f /var/log/syslog&lt;/code&gt;&lt;br&gt;
Deployments: Place production code in &lt;code&gt;/var/www.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;sudo git clone &amp;lt;repo&amp;gt; /var/www/html&lt;/code&gt;&lt;br&gt;
Installations: Use &lt;code&gt;sudo apt install … — packages go into /usr/bin, /usr/lib&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Scratch Work: Use /tmp for temporary files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 Conclusion&lt;/strong&gt;&lt;br&gt;
For a DevOps engineer, knowing the Linux file system is like knowing the map of a city. You need to know where to live (/home), where the government offices are (/etc), where the logs are kept (/var/log), and where the factories produce tools (/usr/bin). Once you master this structure, you’ll navigate servers confidently, troubleshoot faster, and deploy with precision.&lt;/p&gt;

</description>
      <category>git</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>Git -&gt; Quick Drill Sheet</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Sun, 22 Mar 2026 16:38:40 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/git-quick-drill-sheet-3ifg</link>
      <guid>https://dev.to/nagesh_k_2003/git-quick-drill-sheet-3ifg</guid>
      <description>&lt;p&gt;&lt;strong&gt;Important concepts you understood:&lt;/strong&gt;&lt;br&gt;
Working Directory 👉 Where you edit files&lt;br&gt;
Staging Area      👉 Temporary place before commit&lt;br&gt;
Commit            👉 Snapshot of project&lt;br&gt;
Local Repository  👉 Git history on your machine&lt;br&gt;
Remote Repository 👉 GitHub copy of your project&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git Workflow (Most Important) : Always remember this pipeline.&lt;/strong&gt;&lt;br&gt;
Working Directory&lt;br&gt;
      ↓&lt;br&gt;
git add&lt;br&gt;
      ↓&lt;br&gt;
Staging Area&lt;br&gt;
      ↓&lt;br&gt;
git commit&lt;br&gt;
      ↓&lt;br&gt;
Local Repository&lt;br&gt;
      ↓&lt;br&gt;
git push&lt;br&gt;
      ↓&lt;br&gt;
GitHub&lt;/p&gt;

&lt;p&gt;Faster shortcut (useful for single file edits)&lt;br&gt;
git commit -am "updating git_notes.txt"&lt;br&gt;
Reason: -a automatically stages modified files (not new files).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Key Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Repository files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo "text" &amp;gt; file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initialize git&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global config&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git config --global user.name "Alice"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global config&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git config --global user.email "mail.com"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check repo status / See modified, staged, and branch info&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Staging area&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;git add file&lt;/code&gt; / &lt;code&gt;git add .&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Undo staging&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git reset file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;add remote origin&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git remote add origin &amp;lt;repo-URL&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commit changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git commit -m "message"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Push to GitHub&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pull from GitHub&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git pull origin main&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge repos with different histories&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git pull origin main --allow-unrelated-histories&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View commit history&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Short commit history&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git log --oneline&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File-specific history&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git log -- filename&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repository connection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git remote -v&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloning a repo&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git clone &amp;lt;repo-URL&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Branch info&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete empty files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;find . -type f -empty -delete&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete files in Git&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;git rm file&lt;/code&gt; + &lt;code&gt;git commit&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;create + switch branch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git checkout -b &amp;lt;branch name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch branches(new way)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git switch branchname and git switch -c newbranch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Branch info&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;git branch&lt;/code&gt; =&amp;gt; * feature1 , main&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;delete Branch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git branch -d &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Core workflow you practiced&lt;br&gt;
Edit file&lt;br&gt;
   ↓&lt;br&gt;
git add .&lt;br&gt;
   ↓&lt;br&gt;
git commit -m "message"&lt;br&gt;
   ↓&lt;br&gt;
git push&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%2Fin8yuuqex8g7x6ppv50y.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%2Fin8yuuqex8g7x6ppv50y.png" alt=" " width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Branching Strategy :-
&lt;/h2&gt;

&lt;p&gt;git checkout -b newfeature      | new branch from main branch&lt;br&gt;
edit files                      | edit the files&lt;br&gt;
git add README.md               | staging&lt;br&gt;
git commit -m "update"          | commit changes&lt;br&gt;
git push origin newfeature      | push updates in new branch&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;------ CODE REVIEW HAPPENS HERE ------&lt;/strong&gt;&lt;br&gt;
Pull Request → reviewers check code → CI tests run → approval&lt;/p&gt;

&lt;p&gt;git checkout main               | switch to main branch&lt;br&gt;
git merge newfeature            | merge the newfeature to main branch&lt;br&gt;
git push origin main            | to get updated content &lt;br&gt;
git branch -d newfeature        | delete the feature branch&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
    </item>
    <item>
      <title>Real World vs Theory Lessons</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Sun, 22 Mar 2026 16:02:17 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/real-world-vs-theory-lessons-2flf</link>
      <guid>https://dev.to/nagesh_k_2003/real-world-vs-theory-lessons-2flf</guid>
      <description>&lt;p&gt;In theory, checking disk usage looks simple — just grab the percentage from df -h. But in the real world, scripts break, formats differ, and human‑readable values like 374G don’t compare cleanly. This post is about the lessons learned when theory meets reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disk Usage Monitoring in Linux: Percentage vs. Actual Size
&lt;/h2&gt;

&lt;p&gt;Monitoring disk usage is one of the most common tasks for system administrators and developers. But there’s often confusion between checking percentage usage (df -h) and checking actual disk space (du -sh with numfmt). Let’s break down the challenges, solutions, pros, and cons of each approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❓ Common Questions&lt;/strong&gt;&lt;br&gt;
Should I monitor disk usage by percentage or by actual size?&lt;br&gt;
Why does my script fail with “integer expression expected” errors?&lt;br&gt;
How can I compare human‑readable sizes like 192K, 374G, or 2T against thresholds?&lt;br&gt;
Which method is more reliable across different environments (Linux, Git Bash, macOS)?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚡ The Challenge&lt;/strong&gt;&lt;br&gt;
Using df -h with percentages&lt;br&gt;
A typical script might 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;&lt;span class="nv"&gt;disk_usage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR&amp;gt;1 {print $5}'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/%//'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;usage &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$disk_usage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$usage&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 70 &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;"Warning: Disk usage is high (&lt;/span&gt;&lt;span class="nv"&gt;$usage&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;"Disk usage is normal (&lt;/span&gt;&lt;span class="nv"&gt;$usage&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;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt;&lt;br&gt;
Sometimes df -h outputs values like 374G in other columns.&lt;br&gt;
If parsing isn’t precise, your script may grab 374G instead of 22%.&lt;br&gt;
[ -gt ] only works with integers, so 374G causes integer expression expected errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using du -sh with numfmt&lt;/strong&gt;&lt;br&gt;
A more robust approach is to normalize values into bytes:&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="nv"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&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;bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;numfmt&lt;/span&gt; &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;iec &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;threshold&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;numfmt&lt;/span&gt; &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;iec 100G&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="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$bytes&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$threshold&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;"Disk usage is high: &lt;/span&gt;&lt;span class="nv"&gt;$size&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;"Disk usage is normal: &lt;/span&gt;&lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here:&lt;/strong&gt;&lt;br&gt;
du -sh → gives human‑readable size (192K, 374G, etc.).&lt;br&gt;
numfmt --from=iec → converts those into raw integers (bytes).&lt;br&gt;
Thresholds like 100G, 500M, 2T are also converted into bytes.&lt;br&gt;
Comparisons are now reliable and portable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Solutions&lt;/strong&gt;&lt;br&gt;
For percentage checks: Use df -h | awk 'NR&amp;gt;1 {print $5}' | sed 's/%//' to extract only numeric percentages.&lt;/p&gt;

&lt;p&gt;For actual size checks: Use du -sh + numfmt to convert human‑readable values into integers.&lt;/p&gt;

&lt;p&gt;Hybrid approach: Monitor both percentage and actual size for a complete picture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📊 Pros and Cons&lt;/strong&gt;&lt;br&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%2Fmdca9a2ku4qiemmm0or0.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%2Fmdca9a2ku4qiemmm0or0.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Conclusion&lt;/strong&gt;&lt;br&gt;
If you just want a quick warning when usage exceeds 70%, percentage checks with df -h are fine.&lt;br&gt;
If you need robust monitoring across environments, or want to enforce thresholds like “alert me if usage exceeds 100G,” then numfmt is the best choice.&lt;br&gt;
In real production scripts, combining both methods gives the most reliable monitoring.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>My Cloud and DevOps Journey : Day 1</title>
      <dc:creator>Nagesh K</dc:creator>
      <pubDate>Sun, 22 Mar 2026 15:47:56 +0000</pubDate>
      <link>https://dev.to/nagesh_k_2003/my-cloud-and-devops-journey-day-1-2d4e</link>
      <guid>https://dev.to/nagesh_k_2003/my-cloud-and-devops-journey-day-1-2d4e</guid>
      <description>&lt;h2&gt;
  
  
  Start From Linux with Shell Scripting for DevOps :
&lt;/h2&gt;

&lt;p&gt;Shell scripting is like learning a new language — at first, the syntax feels cryptic, but every small win builds confidence. Over time, I’ve discovered not just commands, but ways of thinking about automation, problem solving, and DevOps workflows. Here’s a reflection on the lessons, challenges, and insights I’ve gathered so far.&lt;/p&gt;

&lt;p&gt;Early Lessons Learned&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;File and Directory Operations&lt;br&gt;
Use find when you need to search across directories.&lt;br&gt;
Use [ -f ] when you already know the exact path you want to check.&lt;br&gt;
:&amp;gt; filename → resets a file to empty without deleting it.&lt;br&gt;
exit 1 → stops the script at the failure point.&lt;br&gt;
echo $? → inspects the exit code of the last command.&lt;br&gt;
👉 These basics taught me how to control flow and handle files safely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conditional Logic&lt;br&gt;
[ ] → used for conditions (strings, files, etc.).&lt;br&gt;
[[ ]] → more powerful, supports pattern matching.&lt;br&gt;
(( )) → used for arithmetic comparisons.&lt;br&gt;
Commands can run directly in if without [ ].&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;/dev/null → suppresses normal output.&lt;br&gt;
2&amp;gt;&amp;amp;1 → suppresses error messages too.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Challenge: Forgetting spaces inside [ ] caused errors like “command not found”. Lesson: Always put spaces around brackets.&lt;/p&gt;

&lt;p&gt;🔄 Loops: Thinking in Iterations&lt;br&gt;
🛠️ How to Think About Loops&lt;br&gt;
For loop → “Do this for each item.” (fixed list or range).&lt;br&gt;
While loop → “Keep doing this until the condition fails.”&lt;br&gt;
Until loop → “Keep doing this until the condition succeeds.”&lt;br&gt;
Array loop → Use "${array[@]}" with for because you know the items.&lt;/p&gt;

&lt;p&gt;🔄 Types of Loops in Shell&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For Loop
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..5&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Number: &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Use case: Iterating over files in a directory.&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="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.txt
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Processing &lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;While Loop
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt; &lt;span class="nt"&gt;-le&lt;/span&gt; 5 &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Count: &lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;count+1&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use case: Monitoring a service until it starts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Until Loop
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash
&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 5 &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Count: &lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;count+1&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Infinite Loop
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running..."&lt;/span&gt;
  &lt;span class="nb"&gt;sleep &lt;/span&gt;2
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use case: Continuous monitoring tasks.&lt;/p&gt;

&lt;p&gt;Rule of Thumb&lt;br&gt;
Inside loops:&lt;br&gt;
for file in *.sh → no need for [[ ]].&lt;br&gt;
Use [[ ]] for string/pattern conditions.&lt;br&gt;
Use (( )) for numeric conditions.&lt;br&gt;
Outside loops: same rule applies.&lt;/p&gt;

&lt;p&gt;Best Example:&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;#!/bin/bash&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;do
    if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.sh &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;"Shell script: &lt;/span&gt;&lt;span class="nv"&gt;$file&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;/div&gt;



&lt;p&gt;⚙️ DevOps Connection&lt;br&gt;
For loop + [[ ]] → Iterate files and check extensions, permissions, or patterns.&lt;br&gt;
For loop + (( )) → Iterate numbers (like retries, ports, IDs).&lt;br&gt;
While loop → Monitor service status or retry logic.&lt;br&gt;
Until loop → Wait until a condition succeeds (e.g., deployment ready).&lt;/p&gt;

&lt;p&gt;🧩 Challenges We Faced&lt;br&gt;
Parsing errors: Forgetting spaces in [ ].&lt;br&gt;
Percentage vs actual size: df -h vs du -sh.&lt;br&gt;
Suppressing output: Learning &amp;gt;/dev/null 2&amp;gt;&amp;amp;1.&lt;br&gt;
Exit codes: Understanding how echo $? helps debug scripts.&lt;/p&gt;

&lt;p&gt;✅ Key Takeaways&lt;br&gt;
Think in conditions: [ ] for files/strings, [[ ]] for patterns, (( )) for numbers.&lt;br&gt;
Think in loops: For known ranges → for; for monitoring → while; for waiting → until.&lt;br&gt;
Normalize values: Use numfmt to convert human-readable disk sizes into integers.&lt;br&gt;
Fail fast: Use exit 1 to stop at the failure point.&lt;br&gt;
Debug smartly: Use echo $? to check exit codes.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>cloudcomputing</category>
    </item>
  </channel>
</rss>
