<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Bash - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Bash - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 10 May 2026 16:28:36 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/bash/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ The Open Source LLM Agent Handbook: How to Automate Complex Tasks with LangGraph and CrewAI ]]>
                </title>
                <description>
                    <![CDATA[ Ever feel like your AI tools are a bit...well, passive? Like they just sit there, waiting for your next command? Imagine if they could take initiative, break down big problems, and even work together to get things done. That's exactly what LLM agents... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-open-source-llm-agent-handbook/</link>
                <guid isPermaLink="false">683f04aedfb685791a4e8dd2</guid>
                
                    <category>
                        <![CDATA[ llm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ openai ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ agentic AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #agent ]]>
                    </category>
                
                    <category>
                        <![CDATA[ agents ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Beginner Developers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Balajee Asish Brahmandam ]]>
                </dc:creator>
                <pubDate>Tue, 03 Jun 2025 14:20:30 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748956366197/c4dd2bba-430a-4f12-a3d4-becc6707c52e.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Ever feel like your AI tools are a bit...well, passive? Like they just sit there, waiting for your next command? Imagine if they could take initiative, break down big problems, and even work together to get things done.</p>
<p>That's exactly what LLM agents bring to the table. They're changing how we automate complex tasks, and they can help bring our AI ideas to life in a whole new way.</p>
<p>In this article, we'll explore what LLM agents are, how they work, and how you can build your very own using awesome open-source frameworks.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-the-current-state-of-llm-agents">The Current State of LLM Agents</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-from-chatbots-to-autonomous-agents">From Chatbots to Autonomous Agents</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-can-agents-do-today">What Can Agents Do Today?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-whats-available-to-build-with">What's Available to Build With?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-now-is-the-best-time-to-learn">Why Now Is the Best Time to Learn</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-llm-agents-and-why-are-they-a-big-deal">What Are LLM Agents and Why Are They a Big Deal?</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-an-llm">What Is an LLM?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-so-whats-an-llm-agent">So, What’s an LLM Agent?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-does-this-matter">Why Does This Matter?</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-rise-of-open-source-agent-frameworks">The Rise of Open-Source Agent Frameworks</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-popular-open-source-agent-frameworks">Popular Open-Source Agent Frameworks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-these-tools-enable">What These Tools Enable</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-use-a-framework-instead-of-building-from-scratch">Why Use a Framework Instead of Building from Scratch?</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-core-concepts-behind-agent-design">Core Concepts Behind Agent Design</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-the-agent-loop">The Agent Loop</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-key-components-of-an-agent">Key Components of an Agent</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-multi-agent-collaboration">Multi-Agent Collaboration</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-project-automate-your-daily-schedule-from-emails">Project: Automate Your Daily Schedule from Emails</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-were-automating">What We’re Automating</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-1-install-the-required-tools">Step 1: Install the Required Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-define-the-task">Step 2: Define the Task</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-build-the-workflow-with-langgraph">Step 3: Build the Workflow with LangGraph</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-multi-agent-collaboration-with-crewai">Multi-Agent Collaboration with CrewAI</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-crewai">What Is CrewAI?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-sample-roles-for-the-email-summary-task">Sample Roles for the Email Summary Task</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-sample-crewai-code">Sample CrewAI Code</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-what-actually-happens-during-execution">What Actually Happens During Execution?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-are-llm-agents-safe-what-to-know-about-security-and-privacy">Are LLM Agents Safe? What to Know About Security and Privacy</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-troubleshooting-and-tips">Troubleshooting &amp; Tips</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-explore-more-daily-automations">Explore More Daily Automations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-whats-next-in-agent-technology">What’s Next in Agent Technology?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-summary">Final Summary</a></p>
</li>
</ol>
<h2 id="heading-the-current-state-of-llm-agents">The Current State of LLM Agents</h2>
<p>LLM agents are one of the most exciting developments in AI right now. They’re already helping automate real tasks but they’re also still evolving. So where are we today?</p>
<h3 id="heading-from-chatbots-to-autonomous-agents">From Chatbots to Autonomous Agents</h3>
<p>Large Language Models (LLMs) like GPT-4, Claude, Gemini, and LLaMA have evolved from simple chatbots into surprisingly capable reasoning engines. They've gone from answering trivia questions and generating essays to performing complex reasoning, following multi-step instructions, and interacting with tools like web search and code interpreters.</p>
<p>But here’s the catch: these models are <strong>reactive</strong>. They wait for input and give output. They don't retain memory between tasks, plan ahead, or pursue goals on their own. That’s where <strong>LLM agents</strong> come in – they bridge this gap by adding structure, memory, and autonomy.</p>
<h3 id="heading-what-can-agents-do-today">What Can Agents Do Today?</h3>
<p>Right now, LLM agents are already being used for:</p>
<ul>
<li><p>Summarizing emails or documents</p>
</li>
<li><p>Planning daily schedules</p>
</li>
<li><p>Running DevOps scripts</p>
</li>
<li><p>Searching APIs or tools for answers</p>
</li>
<li><p>Collaborating in small “teams” to complete complex tasks</p>
</li>
</ul>
<p>But they’re not perfect yet. Agents can still:</p>
<ul>
<li><p>Get stuck in loops</p>
</li>
<li><p>Misunderstand goals</p>
</li>
<li><p>Require detailed prompts and guardrails</p>
</li>
</ul>
<p>That’s because this technology is still early-stage. Frameworks are getting better fast, but reliability and memory are still works in progress. So just keep that in mind as you experiment.</p>
<h3 id="heading-why-now-is-the-best-time-to-learn">Why Now Is the Best Time to Learn</h3>
<p>The truth is: we’re still early. But not <em>too</em> early.</p>
<p>This is the perfect time to start experimenting with agents:</p>
<ul>
<li><p>The tooling is mature enough to build real projects</p>
</li>
<li><p>The community is growing rapidly</p>
</li>
<li><p>And you don’t need to be an AI expert just comfortable with Python</p>
</li>
</ul>
<h2 id="heading-what-are-llm-agents-and-why-are-they-a-big-deal">What Are LLM Agents and Why Are They a Big Deal?</h2>
<p>Before we dive into the exciting world of agents, let's quickly chat a bit more about the basics.</p>
<h3 id="heading-what-is-an-llm">What Is an LLM?</h3>
<p>An LLM, or Large Language Model, is basically an AI that's learned from a massive amount of text from the internet – think books, articles, code, and tons more. You can picture it as a super-smart autocomplete engine. But it does way more than just finish your sentences. It can also:</p>
<ul>
<li><p>Answer tricky questions</p>
</li>
<li><p>Summarize long articles or documents</p>
</li>
<li><p>Write code, emails, or creative stories</p>
</li>
<li><p>Translate languages instantly</p>
</li>
<li><p>Even solve logic puzzles and have engaging conversations</p>
</li>
</ul>
<p>Chances are you've heard of ChatGPT, which is powered by OpenAI's GPT models. Other popular LLMs you might come across include Claude (from Anthropic), LLaMA (by Meta), Mistral, and Gemini (from Google).</p>
<p>These models work by simply predicting the next word in a sentence based on the context. While that sounds straightforward, when trained on billions of words, LLMs become capable of surprisingly intelligent behavior, understanding your instructions, following step-by-step reasoning, and producing coherent responses across almost any topic you can imagine.</p>
<h3 id="heading-so-whats-an-llm-agent">So, What’s an LLM Agent?</h3>
<p>While LLMs are super powerful, they usually just <em>react –</em> they only respond when you ask them something. An LLM agent, on the other hand, is <em>proactive</em>.</p>
<p>LLM agents can:</p>
<ul>
<li><p>Break down big, complex tasks into smaller, manageable steps</p>
</li>
<li><p>Make smart decisions and figure out what to do next</p>
</li>
<li><p>Use "tools" like web search, calculators, or even other apps</p>
</li>
<li><p>Work towards a goal, even if it takes multiple steps or tries</p>
</li>
<li><p>Team up with other agents to accomplish shared objectives</p>
</li>
</ul>
<p>In short, LLM agents can think, plan, act, and adapt.</p>
<p>Think of an LLM agent like your super-efficient new assistant: you give it a goal, and it figures out how to achieve it all on its own.</p>
<h3 id="heading-why-does-this-matter">Why Does This Matter?</h3>
<p>This shift from just responding to actively pursuing goals opens a ton of exciting possibilities:</p>
<ul>
<li><p>Automating boring IT or DevOps tasks</p>
</li>
<li><p>Generating detailed reports from raw data</p>
</li>
<li><p>Helping you with multi-step research projects</p>
</li>
<li><p>Reading through your daily emails and highlighting key info</p>
</li>
<li><p>Running your internal tools to take real-world actions</p>
</li>
</ul>
<p>Unlike older, rule-based bots, LLM agents can reason, reflect, and learn from their attempts. This makes them a much better fit for real-world tasks that are messy, require flexibility, and depend on understanding context.</p>
<h2 id="heading-the-rise-of-open-source-agent-frameworks">The Rise of Open-Source Agent Frameworks</h2>
<p>Not too long ago, if you wanted to build an AI system that could act autonomously, it meant writing a ton of custom code, painstakingly managing memory, and trying to stitch together dozens of components. It was a complex, delicate, and highly specialized job.</p>
<p>But guess what? That's not the case anymore.</p>
<p>In 2024, a wave of fantastic open-source frameworks hit the scene. These tools have made it dramatically easier to build powerful LLM agents without you having to reinvent the wheel every time.</p>
<h3 id="heading-popular-open-source-agent-frameworks">Popular Open-Source Agent Frameworks</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Framework</strong></td><td><strong>Description</strong></td><td><strong>Maintainer</strong></td></tr>
</thead>
<tbody>
<tr>
<td>LangGraph</td><td>Graph-based framework for agent state and memory</td><td>LangChain</td></tr>
<tr>
<td>CrewAI</td><td>"Role-based, multi-agent collaboration engine"</td><td>Community (CrewAI)</td></tr>
<tr>
<td>AutoGen</td><td>Customizable multi-agent chat orchestration</td><td>Microsoft</td></tr>
<tr>
<td>AgentVerse</td><td>Modular framework for agent simulation and testing</td><td>Open-source project</td></tr>
</tbody>
</table>
</div><h3 id="heading-what-these-tools-enable">What These Tools Enable</h3>
<p>These frameworks give you ready-made building blocks to handle the trickier parts of creating agents:</p>
<ul>
<li><p><strong>Planning</strong> – Letting agents decide their next move</p>
</li>
<li><p><strong>Tool Use</strong> – Easily connecting agents to things like file systems, web browsers, APIs, or databases</p>
</li>
<li><p><strong>Memory</strong> – Storing and retrieving past information or intermediate results for long-term context</p>
</li>
<li><p><strong>Multi-Agent Collaboration</strong> – Setting up teams of agents that work together on shared goals</p>
</li>
</ul>
<h3 id="heading-why-use-a-framework-instead-of-building-from-scratch">Why Use a Framework Instead of Building from Scratch?</h3>
<p>While you <em>could</em> build a custom agent from the ground up, using a framework will save you a huge amount of time and effort. Open-source agent libraries come packed with:</p>
<ul>
<li><p>Built-in support for orchestrating LLMs</p>
</li>
<li><p>Proven patterns for task planning, keeping track of where you are, and getting feedback</p>
</li>
<li><p>Easy integration with popular models like OpenAI, or even models you run locally</p>
</li>
<li><p>The flexibility to grow from a single helpful agent to entire teams of agents</p>
</li>
</ul>
<p>Basically, these frameworks let you focus on <strong>what your agent should do</strong>, rather than getting bogged down in how to build all the internal workings. Plus, choosing open source means you benefit from community contributions, transparency in how they work, and the freedom to tweak them to your exact needs, without getting locked into a single vendor.</p>
<h2 id="heading-core-concepts-behind-agent-design">Core Concepts Behind Agent Design</h2>
<p>To really grasp how LLM agents operate, it helps to think of them as goal-driven systems that constantly cycle through observing, reasoning, and acting. This continuous loop allows them to tackle tasks that go beyond simple questions and answers, moving into true automation, tool usage, and adapting on the fly.</p>
<h3 id="heading-the-agent-loop">The Agent Loop</h3>
<p>Most LLM agents function based on a mental model called the <strong>Agent Loop</strong> a step-by-step cycle that repeats until the job is done. Here’s how it typically works:</p>
<ul>
<li><p><strong>Perceive:</strong> The agent starts by noticing something in its environment or receiving new information. This could be your prompt, a piece of data, or the current state of a system.</p>
</li>
<li><p><strong>Plan:</strong> Based on what it perceives and its overall goal, the agent decides what to do next. It might break the task into smaller sub-goals or figure out the best tool for the job.</p>
</li>
<li><p><strong>Act:</strong> The agent then acts. This could mean running a function, calling an API, searching the web, interacting with a database, or even asking another agent for help.</p>
</li>
<li><p><strong>Reflect:</strong> After acting, the agent looks at the outcome: Did it work? Was the result useful? Should it try a different approach? Based on this, it updates its plan and keeps going until the task is complete.</p>
</li>
</ul>
<p>This loop is what makes agents so dynamic. It allows them to handle ever-changing tasks, learn from partial results, and correct their course qualities that are vital for building truly useful AI assistants.</p>
<h3 id="heading-key-components-of-an-agent">Key Components of an Agent</h3>
<p>To do their job effectively, agents are built around several crucial parts:</p>
<ul>
<li><p><strong>Tools</strong> are how an agent interacts with the real (or digital) world. These can be anything from search engines, code execution environments, file readers, or API clients, to simple calculators or command-line scripts.</p>
</li>
<li><p><strong>Memory</strong> lets agents remember what they've done or seen across different steps. This might include previous things you've said, temporary results, or key decisions. Some frameworks offer short-term memory (just for one session), while others support long-term memory that can span multiple sessions or goals.</p>
</li>
<li><p><strong>Environment</strong> refers to the external data or system context the agent operates within think APIs, documents, databases, files, or sensor inputs. The more information and access an agent have to its environment, the more meaningful actions it can take.</p>
</li>
<li><p><strong>Goal</strong> is the agent's ultimate objective: what it's trying to achieve. Goals should be specific and clear for instance, “generate a daily schedule,” “summarize this document,” or “extract tasks from emails.”</p>
</li>
</ul>
<h3 id="heading-multi-agent-collaboration">Multi-Agent Collaboration</h3>
<p>For more advanced systems, you can even have multiple agents working together to hit a shared target. Each agent can be given a specific <strong>role</strong> that highlights its specialty just like people working on a team.</p>
<p>For example:</p>
<ul>
<li><p>A <strong>researcher agent</strong> might be tasked with gathering information.</p>
</li>
<li><p>A <strong>coder agent</strong> could write Python scripts or automation routines.</p>
</li>
<li><p>A <strong>reviewer agent</strong> might check the results and ensure everything is up to snuff.</p>
</li>
</ul>
<p>These agents can chat with each other, share information, and even debate or vote on decisions. This kind of teamwork allows AI systems to tackle bigger, more complex tasks while keeping things organized and modular.</p>
<h2 id="heading-project-automate-your-daily-schedule-from-emails">Project: Automate Your Daily Schedule from Emails</h2>
<h3 id="heading-what-were-automating">What We’re Automating</h3>
<p>Think about your typical morning routine:</p>
<ul>
<li><p>You open your inbox.</p>
</li>
<li><p>You quickly scan through a bunch of emails.</p>
</li>
<li><p>You try to spot meetings, tasks, and important reminders.</p>
</li>
<li><p>Then, you manually write a to-do list or add things to your calendar.</p>
</li>
</ul>
<p>Let's use an LLM agent to make that process effortless. Our agent will:</p>
<ul>
<li><p>Read a list of your email messages</p>
</li>
<li><p>Pull out time-sensitive items like meetings or deadlines</p>
</li>
<li><p>Summarize everything into a nice, clean daily schedule</p>
</li>
</ul>
<h3 id="heading-step-1-install-the-required-tools">Step 1: Install the Required Tools</h3>
<p>To get started, you'll need three main tools: Python, VSCode, and an OpenAI API key.</p>
<h4 id="heading-1-install-python-39-or-higher">1. Install Python 3.9 or Higher</h4>
<p>Grab the latest version of Python 3.9+ from the official website: <a target="_blank" href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></p>
<p>Once it's installed, double-check it by running <code>python --version</code> in your terminal.</p>
<p>This command simply asks your system to report the Python version currently installed. You'll want to see Python 3.9.x or something higher to ensure compatibility with our project.</p>
<h4 id="heading-2-install-vscode-optional-but-recommended">2. Install VSCode (Optional but Recommended)</h4>
<p>VSCode is a fantastic, user-friendly code editor that works perfectly with Python. You can download it right here: <a target="_blank" href="https://code.visualstudio.com/">https://code.visualstudio.com/</a>.</p>
<h4 id="heading-3-get-your-openai-api-key">3. Get Your OpenAI API Key</h4>
<p>Head over to: https://platform.openai.com</p>
<p>Sign in or create a new account. Navigate to your API Keys page. Click “Create new secret key” and make sure to copy that key somewhere safe for later.</p>
<h4 id="heading-4-install-python-libraries">4. Install Python Libraries</h4>
<p>Open your terminal or command prompt and install these essential packages:</p>
<pre><code class="lang-bash">pip install langgraph langchain openai
</code></pre>
<p>This command uses pip, Python's package manager, to download and install three crucial libraries for our agent:</p>
<ul>
<li><p>langgraph: The core framework we'll use to build our agent's workflow.</p>
</li>
<li><p>langchain: A foundational library for working with large language models, upon which LangGraph is built.</p>
</li>
<li><p>openai: The official Python library for connecting to OpenAI's powerful AI models.</p>
</li>
</ul>
<p>If you're excited to try out multi-agent setups (which we'll cover in Step 5), also install CrewAI:</p>
<pre><code class="lang-bash">pip install crewai
</code></pre>
<p>This command installs CrewAI, a specialized framework that makes it easy to orchestrate multiple AI agents working together as a team.</p>
<p><strong>5. Set Your OpenAI API Key</strong></p>
<p>You need to make sure your Python code can find and use your OpenAI API key. This is typically done by setting it as an environment variable.</p>
<p>On macOS/Linux, run this in your terminal (replace "your-api-key" with your actual key):</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> OPENAI_API_KEY=<span class="hljs-string">"your-api-key"</span>
</code></pre>
<p>This command sets an environment variable named OPENAI_API_KEY. Environment variables are a secure way for applications (like your Python script) to access sensitive information without hardcoding it directly into the code itself.</p>
<p>On Windows (using Command Prompt), do this:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">set</span> OPENAI_API_KEY=<span class="hljs-string">"your-api-key"</span>
</code></pre>
<p>This is the Windows equivalent command to set the <code>OPENAI_API_KEY</code> environment variable.</p>
<p>Now, your Python code will be all set to talk to the OpenAI model!</p>
<h3 id="heading-step-2-define-the-task">Step 2: Define the Task</h3>
<p>We discussed this briefly in the beginning of this section. But to reiterate, this is what we’ll want our agent to do:</p>
<ul>
<li><p>Scan for meetings, events, and important tasks.</p>
</li>
<li><p>Jot them down quickly in a notebook or an app.</p>
</li>
<li><p>Create a rough mental plan for your day.</p>
</li>
</ul>
<p>This routine takes time and mental energy. So having an agent do it for us will be super helpful.</p>
<h3 id="heading-step-3-build-the-workflow-with-langgraph">Step 3: Build the Workflow with LangGraph</h3>
<h4 id="heading-what-is-langgraph">What Is LangGraph?</h4>
<p>LangGraph is a cool framework that helps you build agents using a "graph-based" workflow, kind of like drawing a flowchart. It's powered by LangChain and gives you a lot more control over exactly how each step in your agent's process unfolds.</p>
<p>Each "node" in this graph represents a decision point or a function that:</p>
<ul>
<li><p>Takes some input (its current "state").</p>
</li>
<li><p>Does some reasoning or takes an action (often involving the LLM and its tools).</p>
</li>
<li><p>Returns an updated output (a new "state").</p>
</li>
</ul>
<p>You draw the connections between these nodes, and LangGraph then executes it like a smart, automated state machine.</p>
<h4 id="heading-why-use-langgraph">Why Use LangGraph?</h4>
<ul>
<li><p>You get to control the precise order of execution.</p>
</li>
<li><p>It's fantastic for building workflows that have multiple steps or even branch off into different paths.</p>
</li>
<li><p>It plays nicely with both cloud-based models (like OpenAI) and models you run locally.</p>
</li>
</ul>
<p>Alright – now let’s write the code.</p>
<h5 id="heading-1-simulate-email-input"><strong>1. Simulate Email Input</strong></h5>
<p>In a real application, your agent would probably connect to Gmail or Outlook to fetch your actual emails. For this example, though, we’ll just hardcode some sample messages to keep things simple:</p>
<pre><code class="lang-python">Python

emails = <span class="hljs-string">"""
1. Subject: Standup Call at 10 AM
2. Subject: Client Review due by 5 PM
3. Subject: Lunch with Sarah at noon
4. Subject: AWS Budget Warning – 80% usage
5. Subject: Dentist Appointment - 4 PM
"""</span>
</code></pre>
<p>This multiline Python string, <code>emails</code>, acts as our stand-in for real email content. We're providing a simple, structured list of email subjects to demonstrate how the agent will process text.</p>
<h5 id="heading-2-define-the-agent-logic"><strong>2. Define the Agent Logic</strong></h5>
<p>Now, we'll tell OpenAI’s GPT model how to process this email text and turn it into a summary.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain_openai <span class="hljs-keyword">import</span> ChatOpenAI
<span class="hljs-keyword">from</span> langgraph.graph <span class="hljs-keyword">import</span> StateGraph, END
<span class="hljs-keyword">from</span> typing <span class="hljs-keyword">import</span> TypedDict, Annotated, List
<span class="hljs-keyword">import</span> operator

<span class="hljs-comment"># Define the state for our graph</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AgentState</span>(<span class="hljs-params">TypedDict</span>):</span>
    emails: str
    result: str

llm = ChatOpenAI(temperature=<span class="hljs-number">0</span>, model=<span class="hljs-string">"gpt-4o"</span>) <span class="hljs-comment"># Using gpt-4o for better performance</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">calendar_summary_agent</span>(<span class="hljs-params">state: AgentState</span>) -&gt; AgentState:</span>
    emails = state[<span class="hljs-string">"emails"</span>]
    prompt = <span class="hljs-string">f"Summarize today's schedule based on these emails, listing time-sensitive items first and then other important notes. Be concise and use bullet points:\n<span class="hljs-subst">{emails}</span>"</span>
    summary = llm.invoke(prompt).content
    <span class="hljs-keyword">return</span> {<span class="hljs-string">"result"</span>: summary, <span class="hljs-string">"emails"</span>: emails} <span class="hljs-comment"># Ensure emails is also returned</span>
</code></pre>
<p>Here’s what’s going on:</p>
<ul>
<li><p><strong>Imports</strong>: We bring in necessary components:</p>
<ul>
<li><p><code>ChatOpenAI</code> to connect to the LLM,</p>
</li>
<li><p><code>StateGraph</code> and <code>END</code> from <code>langgraph.graph</code> to build our agent workflow,</p>
</li>
<li><p><code>TypedDict</code>, <code>Annotated</code>, and <code>List</code> from <code>typing</code> for type checking and structure,</p>
</li>
<li><p><code>operator</code> (though not used in this snippet, it can help with comparisons or logic).</p>
</li>
</ul>
</li>
<li><p><strong>AgentState</strong>: This <code>TypedDict</code> defines the shape of the data our agent will work with. It includes:</p>
<ul>
<li><p><code>emails</code>: the raw input messages.</p>
</li>
<li><p><code>result</code>: the final output (the daily summary).</p>
</li>
</ul>
</li>
<li><p><strong>llm = ChatOpenAI(...)</strong>: Initializes the language model. We're using GPT-4o with <code>temperature=0</code> to ensure consistent, predictable output perfect for structured summarization tasks.</p>
</li>
<li><p><strong>calendar_summary_agent(state: AgentState)</strong>: This function is the "brain" of our agent. It:</p>
<ul>
<li><p>Takes in the current state, which includes a list of emails.</p>
</li>
<li><p>Extracts the emails from that state.</p>
</li>
<li><p>Constructs a prompt that tells the model to generate a concise daily schedule summary using bullet points, prioritizing time-sensitive items.</p>
</li>
<li><p>Sends this prompt to the model with <code>llm.invoke(prompt).content</code>, which returns the LLM’s response as plain text.</p>
</li>
<li><p>Returns a new <code>AgentState</code> dictionary containing:</p>
<ul>
<li><p><code>result</code>: the generated summary,</p>
</li>
<li><p><code>emails</code>: preserved in case we need it downstream.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h5 id="heading-3-build-and-run-the-graph"><strong>3. Build and Run the Graph</strong></h5>
<p>Now, let's use LangGraph to map out the flow of our single-agent task and then run it.</p>
<pre><code class="lang-python">builder = StateGraph(AgentState)
builder.add_node(<span class="hljs-string">"calendar"</span>, calendar_summary_agent)
builder.set_entry_point(<span class="hljs-string">"calendar"</span>)
builder.set_finish_point(<span class="hljs-string">"calendar"</span>) <span class="hljs-comment"># END is implicit if not set explicitly</span>

graph = builder.compile()

<span class="hljs-comment"># Run the graph using your simulated email data</span>
result = graph.invoke({<span class="hljs-string">"emails"</span>: emails})
print(result[<span class="hljs-string">"result"</span>])
</code></pre>
<p>Here’s what’s going on:</p>
<ul>
<li><p><strong>builder = StateGraph(AgentState):</strong> We're initiating a StateGraph object. By passing AgentState, we're telling LangGraph the expected data structure for its internal state.</p>
</li>
<li><p><strong>builder.add_node("calendar", calendar_summary_agent):</strong> This line adds a named "node" to our graph. We're calling it "calendar", and we're linking it to our <code>calendar_summary_agent</code> function, meaning that function will be executed when this node is active.</p>
</li>
<li><p><strong>builder.set_entry_point("calendar"):</strong> This sets "calendar" as the very first step in our workflow. When we start the graph, execution will begin here.</p>
</li>
<li><p><strong>builder.set_finish_point("calendar"):</strong> This tells LangGraph that once the "calendar" node finishes its job, the entire graph process is complete.</p>
</li>
<li><p><strong>graph = builder.compile():</strong> This command takes our defined graph blueprint and "compiles" it into an executable workflow.</p>
</li>
<li><p><strong>result = graph.invoke({"emails": emails}):</strong> This is where the magic happens! We're telling our graph to start running. We pass it an initial state that contains our emails data. The graph will then process this data through its nodes until it reaches an end point, returning the final state.</p>
</li>
<li><p><strong>print(result["result"]):</strong> Finally, we grab the summarized schedule from the result (the final state of our graph) and print it to the console.</p>
</li>
</ul>
<h4 id="heading-example-output">Example Output</h4>
<p><code>Your Schedule:</code><br><code>- 10:00 AM – Standup Call</code><br><code>- 12:00 PM – Lunch with Sarah</code><br><code>- 4:00 PM – Dentist Appointment</code><br><code>- Submit client report by 5:00 PM</code><br><code>- AWS Budget Warning – check usage</code></p>
<p>Boom! You've just built an AI agent that can read your emails and whip up your daily schedule. Pretty cool, right? This is a simple yet powerful peek into what LLM agents can do with just a few lines of code.</p>
<h2 id="heading-multi-agent-collaboration-with-crewai">Multi-Agent Collaboration with CrewAI</h2>
<h3 id="heading-what-is-crewai">What Is CrewAI?</h3>
<p>CrewAI is an exciting open-source framework that lets you build <em>teams</em> of agents that work together seamlessly just like a real-world project team! Each agent in a CrewAI setup:</p>
<ul>
<li><p>Has a specific, specialized role.</p>
</li>
<li><p>Can communicate and share information with its teammates.</p>
</li>
<li><p>Collaborates to achieve a shared goal.</p>
</li>
</ul>
<p>This multi-agent approach is super useful when your task is too big or too complex for just one agent, or when breaking it down into specialized parts makes it clearer and more efficient.</p>
<h3 id="heading-sample-roles-for-the-email-summary-task">Sample Roles for the Email Summary Task</h3>
<p>Let's imagine our email summary task being handled by a small team of agents:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Agent Name</strong></td><td><strong>Role</strong></td><td><strong>Responsibility</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Extractor</td><td>Email Scanner</td><td>"Find meetings, reminders, and tasks from emails"</td></tr>
<tr>
<td>Prioritizer</td><td>Schedule Optimizer</td><td>Sort items by urgency and time</td></tr>
<tr>
<td>Formatter</td><td>Output Generator</td><td>"Write a clean, polished daily agenda"</td></tr>
</tbody>
</table>
</div><h3 id="heading-sample-crewai-code">Sample CrewAI Code</h3>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> crewai <span class="hljs-keyword">import</span> Agent, Crew, Task, Process
<span class="hljs-keyword">from</span> langchain_openai <span class="hljs-keyword">import</span> ChatOpenAI
<span class="hljs-keyword">import</span> os

<span class="hljs-comment"># Set your OpenAI API key from environment variables</span>
<span class="hljs-comment"># os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY" # Make sure this is set, or defined directly</span>

<span class="hljs-comment"># Initialize the LLM (using gpt-4o for better performance)</span>
llm = ChatOpenAI(temperature=<span class="hljs-number">0</span>, model=<span class="hljs-string">"gpt-4o"</span>)

<span class="hljs-comment"># Define the agents with specific roles and goals</span>
extractor = Agent(
    role=<span class="hljs-string">"Email Scanner"</span>,
    goal=<span class="hljs-string">"Find all meetings, reminders, and tasks from the given emails, accurately extracting details like time, date, and subject."</span>,
    backstory=<span class="hljs-string">"You are an expert at scanning emails for key information. You meticulously extract every relevant detail."</span>,
    verbose=<span class="hljs-literal">True</span>,
    allow_delegation=<span class="hljs-literal">False</span>,
    llm=llm
)

prioritizer = Agent(
    role=<span class="hljs-string">"Schedule Optimizer"</span>,
    goal=<span class="hljs-string">"Sort extracted items by urgency and time, preparing them for a daily agenda."</span>,
    backstory=<span class="hljs-string">"You are a master of time management, always knowing what needs to be done first. You organize tasks logically."</span>,
    verbose=<span class="hljs-literal">True</span>,
    allow_delegation=<span class="hljs-literal">False</span>,
    llm=llm
)

formatter = Agent(
    role=<span class="hljs-string">"Output Generator"</span>,
    goal=<span class="hljs-string">"Generate a clean, polished, and concise daily agenda in bullet-point format, clearly listing all schedule items."</span>,
    backstory=<span class="hljs-string">"You are a professional secretary, ensuring all outputs are perfectly formatted and easy to read. You prioritize clarity."</span>,
    verbose=<span class="hljs-literal">True</span>,
    allow_delegation=<span class="hljs-literal">False</span>,
    llm=llm
)

<span class="hljs-comment"># Simulate email input</span>
emails = <span class="hljs-string">"""
1. Subject: Standup Call at 10 AM
2. Subject: Client Review due by 5 PM
3. Subject: Lunch with Sarah at noon
4. Subject: AWS Budget Warning – 80% usage
5. Subject: Dentist Appointment - 4 PM
"""</span>

<span class="hljs-comment"># Define the tasks for each agent</span>
extract_task = Task(
    description=<span class="hljs-string">f"Extract all relevant events, meetings, and tasks from these emails: <span class="hljs-subst">{emails}</span>. Focus on precise details."</span>,
    agent=extractor,
    expected_output=<span class="hljs-string">"A list of extracted items with their details (e.g., '- Standup Call at 10 AM', '- Client Review due by 5 PM')."</span>
)

prioritize_task = Task(
    description=<span class="hljs-string">"Prioritize the extracted items by time and urgency. Meetings first, then deadlines, then other notes."</span>,
    agent=prioritizer,
    context=[extract_task], <span class="hljs-comment"># The output of extract_task is the input here</span>
    expected_output=<span class="hljs-string">"A prioritized list of schedule items."</span>
)

format_task = Task(
    description=<span class="hljs-string">"Format the prioritized schedule into a clean, easy-to-read daily agenda using bullet points. Ensure concise language."</span>,
    agent=formatter,
    context=[prioritize_task], <span class="hljs-comment"># The output of prioritize_task is the input here</span>
    expected_output=<span class="hljs-string">"A well-formatted daily agenda with bullet points."</span>
)

<span class="hljs-comment"># Instantiate the crew</span>
crew = Crew(
    agents=[extractor, prioritizer, formatter],
    tasks=[extract_task, prioritize_task, format_task],
    process=Process.sequential, <span class="hljs-comment"># Tasks are executed sequentially</span>
    verbose=<span class="hljs-number">2</span> <span class="hljs-comment"># Outputs more details during execution</span>
)

<span class="hljs-comment"># Run the crew</span>
result = crew.kickoff()
print(<span class="hljs-string">"\n########################"</span>)
print(<span class="hljs-string">"## Final Daily Agenda ##"</span>)
print(<span class="hljs-string">"########################\n"</span>)
print(result)
</code></pre>
<p>Here’s what’s going on:</p>
<ul>
<li><p><strong>Imports:</strong> We bring in key classes from CrewAI: Agent, Crew, Task, and Process. We also import <code>ChatOpenAI</code> for our language model and os to handle environment variables.</p>
</li>
<li><p><strong>llm = ChatOpenAI(...):</strong> Just like in the LangGraph example, this sets up our OpenAI language model, making sure its responses are direct (temperature=0) and using the gpt-4o model.</p>
</li>
<li><p><strong>Agent Definitions (extractor, prioritizer, formatter):</strong></p>
<ul>
<li><p>Each of these variables creates an Agent instance. An agent is defined by its role (what it does), a specific goal it's trying to achieve, and a backstory (a sort of personality or expertise that helps the LLM understand its purpose better).</p>
</li>
<li><p>verbose=True is super helpful for debugging, as it makes the agents print out their "thoughts" as they work.</p>
</li>
<li><p>allow_delegation=False means these agents won't pass their assigned tasks to other agents (though this can be set to True for more complex delegation scenarios).</p>
</li>
<li><p>llm=llm connects each agent to our OpenAI language model.</p>
</li>
</ul>
</li>
<li><p><strong>Simulated emails:</strong> We reuse the same sample email data for this example.</p>
</li>
<li><p><strong>Task Definitions (extract_task, prioritize_task, format_task):</strong></p>
<ul>
<li><p>Each Task defines a specific piece of work that an agent needs to perform.</p>
</li>
<li><p>description clearly tells the agent what the task involves.</p>
</li>
<li><p>agent assigns this task to one of our defined agents (e.g., extractor for extract_task).</p>
</li>
<li><p>context=[...] is a critical part of CrewAI's collaboration. It tells a task to use the <em>output</em> of a previous task as its <em>input</em>. For instance, prioritize_task takes the extract_task's output as its context.</p>
</li>
<li><p>expected_output gives the agent an idea of what its result should look like, helping guide the LLM.</p>
</li>
</ul>
</li>
<li><p><strong>crew = Crew(...):</strong></p>
<ul>
<li><p>This is where we assemble our team! We create a Crew instance, giving it our list of agents and tasks.</p>
</li>
<li><p>process=Process.sequential tells the crew to execute tasks one after another in the order they're defined in the tasks list. CrewAI also supports more advanced processes like hierarchical ones.</p>
</li>
<li><p>verbose=2 will show you a very detailed log of the crew's internal workings and communication.</p>
</li>
</ul>
</li>
<li><p><strong>result = crew.kickoff():</strong> This command officially starts the entire multi-agent workflow. The agents will begin collaborating, passing information, and working through their assigned tasks in sequence.</p>
</li>
<li><p><strong>fprint(result):</strong> Finally, the consolidated output from the entire crew's collaborative effort is printed to your console.</p>
</li>
</ul>
<p>CrewAI cleverly handles all the communication between agents, figures out who needs to work on what and when, and passes the output smoothly from one agent to the next it's like having a mini AI assembly line!</p>
<h2 id="heading-what-actually-happens-during-execution">What Actually Happens During Execution?</h2>
<p>So, whether you're using LangGraph or CrewAI, what's really going on behind the scenes when an agent runs? Let's break down the execution process:</p>
<ul>
<li><p>The system gets an <strong>input state</strong> (for example, your emails).</p>
</li>
<li><p>The first agent or graph node reads this input and uses a <strong>Large Language Model (LLM)</strong> to make sense of it.</p>
</li>
<li><p>Based on its understanding, the agent decides on an <strong>action</strong> like pulling out key events or calling a specific tool.</p>
</li>
<li><p>If needed, the agent might <strong>invoke tools</strong> (like a web search or a file reader) to get more context or perform external operations.</p>
</li>
<li><p>The result of that action is then <strong>passed to the next agent</strong> in the team (if it's a multi-agent setup) or returned directly to you.</p>
</li>
</ul>
<p>Execution keeps going until:</p>
<ul>
<li><p>The task is fully completed.</p>
</li>
<li><p>All agents have finished their assigned roles.</p>
</li>
<li><p>A stopping condition or a designated "END" point in the workflow is reached.</p>
</li>
</ul>
<p>Think of this as a super-smart workflow engine where every single step involves reasoning, making decisions, and remembering previous interactions.</p>
<h2 id="heading-are-llm-agents-safe-what-to-know-about-security-and-privacy">Are LLM Agents Safe? What to Know About Security and Privacy</h2>
<p>As cool as LLM agents are, they raise an important question: <em>can you really trust an AI to run parts of your workflow or interact with your data?</em> It depends. If you’re using services like OpenAI or Anthropic, your data is encrypted in transit and (as of now) isn’t used for training.</p>
<p>But some data might still be temporarily logged to prevent abuse. That’s usually fine for testing and personal projects, but if you’re working with sensitive business info, customer data, or anything private, you’ll want to be careful.</p>
<p>Use anonymized inputs, avoid exposing full datasets, and consider running agents locally using open-source models like LLaMA or Mistral if full control matters to you.</p>
<p>You can also set clear boundaries for your agents so they don’t overstep. Think of it like onboarding a new intern: you wouldn’t give them access to everything on day one.</p>
<p>Give agents only the tools and files they need, keep logs of what they do, and always review the results before letting them make real changes.</p>
<p>As this tech grows, more safety features are coming like better sandboxing, memory limits, and role-based access. But for now, it’s smart to treat your agents like powerful helpers that still need some human supervision.</p>
<h2 id="heading-troubleshooting-amp-tips">Troubleshooting &amp; Tips</h2>
<p>Sometimes, agents can be a bit quirky! Here are some common issues you might run into and how to fix them:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Issue</strong></td><td><strong>Suggested Fix</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Agent seems to loop forever</td><td>Set a maximum number of iterations or define a clearer stopping point.</td></tr>
<tr>
<td>Output is too chatty or verbose</td><td>Use more specific prompts (for example, “Respond in bullet points only”).</td></tr>
<tr>
<td>Input is too long or gets cut off</td><td>Break down large pieces of content into smaller chunks and summarize them individually.</td></tr>
<tr>
<td>Agent runs too slowly</td><td>Try using a faster LLM model like gpt-3.5 or consider running a local model.</td></tr>
</tbody>
</table>
</div><p>A handy tip: You can also add print() statements or logging messages inside your agent functions to see what's happening at each stage and debug state transitions.</p>
<h2 id="heading-explore-more-daily-automations">Explore More Daily Automations</h2>
<p>Once you've built one agent-based task, you'll find it incredibly easy to adapt the pattern for other automations. Here are some cool ideas to get your creative juices flowing:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Task Type</strong></td><td><strong>Example Automation</strong></td></tr>
</thead>
<tbody>
<tr>
<td>DevOps Assistant</td><td>"Read system logs, detect potential issues, and suggest solutions."</td></tr>
<tr>
<td>Finance Tracker</td><td>Read bank statements or CSV files and summarize your spending habits/budgets.</td></tr>
<tr>
<td>Meeting Organizer</td><td>After a meeting, automatically extract action items and assign owners.</td></tr>
<tr>
<td>Inbox Cleaner</td><td>"Automatically label, archive, and delete non-urgent emails."</td></tr>
<tr>
<td>Note Summarizer</td><td>Convert your daily notes into a neatly formatted to-do list or summary.</td></tr>
<tr>
<td>Link Checker</td><td>Extract URLs from documents and automatically test if they're still valid.</td></tr>
<tr>
<td>Resume Formatter</td><td>Score resumes against job descriptions and format them automatically.</td></tr>
</tbody>
</table>
</div><p>Each of these can be built using the very same principles and frameworks we discussed whether that's LangGraph or CrewAI.</p>
<h2 id="heading-whats-next-in-agent-technology">What’s Next in Agent Technology?</h2>
<p>LLM agents are evolving at lightning speed, and the next wave of innovation is already here:</p>
<ul>
<li><p><strong>Smarter memory systems</strong>: Expect agents to have better long-term memory, allowing them to learn over extended periods and remember past conversations and actions.</p>
</li>
<li><p><strong>Multi-modal agents</strong>: Agents won't just handle text anymore! They'll be able to process and understand images, audio, and video, making them much more versatile.</p>
</li>
<li><p><strong>Advanced planning frameworks</strong>: Techniques like ReAct, Toolformer, and AutoGen are constantly improving agents' ability to reason, plan, and reduce those pesky "hallucinations."</p>
</li>
<li><p><strong>Edge deployment</strong>: Imagine agents running entirely offline on your local computer or device using lightweight models like LLaMA 3 or Mistral.</p>
</li>
</ul>
<p>In the very near future, you'll see agents seamlessly integrated into:</p>
<ul>
<li><p>Your DevOps pipelines</p>
</li>
<li><p>Big enterprise workflows</p>
</li>
<li><p>Everyday productivity tools</p>
</li>
<li><p>Mobile apps and smart devices</p>
</li>
<li><p>Games, simulations, and educational platforms</p>
</li>
</ul>
<h2 id="heading-final-summary">Final Summary</h2>
<p>Alright, let's quickly recap all the cool stuff you've just learned and accomplished:</p>
<ul>
<li><p>You've gotten a solid grasp of what LLM agents are and why they're so powerful.</p>
</li>
<li><p>You've seen how open-source frameworks like LangGraph and CrewAI make building agents much easier.</p>
</li>
<li><p>You've built a real LLM agent using LangGraph to automate a common daily task: summarizing your inbox!</p>
</li>
<li><p>You've explored the world of multi-agent collaboration with CrewAI, understanding how teams of AIs can work together.</p>
</li>
<li><p>You've learned how to take these principles and scale them to automate countless other tasks.</p>
</li>
</ul>
<p>So, next time you find yourself stuck doing something repetitive, just ask yourself: "Hey, can I build an agent for that?" The answer is probably yes!</p>
<h3 id="heading-resources-recap">Resources Recap</h3>
<p>Here are some helpful resources if you want to dive deeper into building LLM agents:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Resource</strong></td><td><strong>Link</strong></td></tr>
</thead>
<tbody>
<tr>
<td>LangGraph Docs</td><td><a target="_blank" href="https://docs.langgraph.dev/">https://docs.langgraph.dev/</a></td></tr>
<tr>
<td>CrewAI GitHub</td><td><a target="_blank" href="https://github.com/joaomdmoura/crewAI">https://github.com/joaomdmoura/crewAI</a></td></tr>
<tr>
<td>LangChain Docs</td><td><a target="_blank" href="https://docs.langchain.com/docs/">https://docs.langchain.com/docs/</a></td></tr>
<tr>
<td>OpenAI API Docs</td><td><a target="_blank" href="https://platform.openai.com/docs">https://platform.openai.com/docs</a></td></tr>
<tr>
<td>Python 3.9+</td><td><a target="_blank" href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></td></tr>
<tr>
<td>VSCode</td><td><a target="_blank" href="https://code.visualstudio.com/">https://code.visualstudio.com/</a></td></tr>
</tbody>
</table>
</div> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What Are Scripts and How Do They Work? Improve Your Productivity with Scripting ]]>
                </title>
                <description>
                    <![CDATA[ Developers who have a lot of experience building rigid, quality software tend to automate most of their work by writing scripts. These scripts range from simple alias bash commands to repetitive cron triggers that run on a server. In this tutorial, y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-are-scripts-and-how-do-they-work/</link>
                <guid isPermaLink="false">679798b5c4e8c2bf2c88f7bc</guid>
                
                    <category>
                        <![CDATA[ scripts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Mon, 27 Jan 2025 14:31:17 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737988076418/347e6d8a-1dd8-45d1-854b-fbc576eeed5f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Developers who have a lot of experience building rigid, quality software tend to automate most of their work by writing scripts. These scripts range from simple alias bash commands to repetitive cron triggers that run on a server.</p>
<p>In this tutorial, you’ll learn about what scripting is, its many use cases, and some advantages and disadvantages of using scripts. We’ll also go through a few example scripts so you can see them in action.</p>
<h2 id="heading-what-is-a-script">What is a Script?</h2>
<p>A script is a set of instructions written in any scripting language (like Bash, Python, JavaScript, and others) that helps you automate tasks or control processes. Unlike compiled programs, scripts are typically <a target="_blank" href="https://www.freecodecamp.org/news/compiled-versus-interpreted-languages/">interpreted</a>, meaning they are executed directly by a runtime environment without prior compilation.</p>
<p>Scripts are powerful tools for automating repetitive tasks, managing workflows, and solving small (and sometimes large) problems efficiently. Whether you’re a beginner or an experienced developer, understanding how to write scripts can enhance your productivity and broaden your technical capabilities.</p>
<h2 id="heading-why-write-scripts">Why Write Scripts?</h2>
<p>I’ve already touched on what you can do with scripts. So let’s look at some of their advantages (and challenges, too) so you understand why they’re so powerful – and when to use them.</p>
<h3 id="heading-advantages-of-scripts">Advantages of scripts</h3>
<ol>
<li><p>Automation: Scripts can help you simplify repetitive tasks such as data processing or file management.</p>
</li>
<li><p>Efficiency: they can also save you time by automating tasks that you would otherwise have to do manually.</p>
</li>
<li><p>Error reduction: Scripts can help reduce human errors through consistent execution of instructions.</p>
</li>
<li><p>Flexibility: Scripts can adapt to a wide variety of tasks with minimal modification.</p>
</li>
<li><p>Integration: They can also seamlessly integrate with other systems, tools, or workflows.</p>
</li>
</ol>
<h3 id="heading-challenges-with-scripts">Challenges with scripts</h3>
<ol>
<li><p>Performance: Scripts can be slower than compiled programs due to interpretation overhead.</p>
</li>
<li><p>Scalability: They’re not always suitable for large-scale or highly complex tasks.</p>
</li>
<li><p>Debugging: Debugging scripts can sometimes be challenging due to their dynamic nature.</p>
</li>
<li><p>Security risks: Poorly written scripts can expose vulnerabilities, especially if they execute system-level commands.</p>
</li>
</ol>
<h3 id="heading-when-to-use-vs-not-use-scripts">When to Use vs Not Use Scripts</h3>
<p>Scripts are ideal for:</p>
<ol>
<li><p>Tasks are simple, well-defined, or one-off</p>
</li>
<li><p>Prototyping or quickly automating a process</p>
</li>
<li><p>The scope is small enough to avoid complexity</p>
</li>
</ol>
<p>Scripts are not ideal for:</p>
<ol>
<li><p>Performance-critical tasks requiring high efficiency. Instead of a script, try using a dedicated ETL (Extract, Transform, Load) tool or a message broker, or similar alternative tools that fit your use-case.</p>
</li>
<li><p>Applications with extensive user interfaces. Instead, you can build a small application or a modular system with proper logging, testing, and documentation.</p>
</li>
<li><p>Scenarios needing long-term maintenance, where compiled programs might be more stable. Instead, use task schedulers or workflow managers like CRON, Airflow, AWS Lambda/GCP Functions.</p>
</li>
</ol>
<h2 id="heading-how-to-write-effective-scripts">How to Write Effective Scripts</h2>
<p>This is the process I use for writing helpful scripts. After we go through this, we’ll see some examples of scripts in different languages so you can get some hands-on practice.</p>
<ol>
<li><p>Define the problem: Before writing a script, identify the problem it will solve. Be clear about the tasks to automate and the expected outcomes.</p>
</li>
<li><p>Choose the right language:</p>
<ul>
<li><p><strong>Bash:</strong> Ideal for system-level tasks like file operations or server management.</p>
</li>
<li><p><strong>Python:</strong> Great for data processing, web scraping, and more complex automation.</p>
</li>
<li><p><strong>JavaScript:</strong> Suited for web development and browser-based automation.</p>
</li>
</ul>
</li>
<li><p>Write the script: Use a text editor or an Integrated Development Environment (IDE), and make sure you follow best practices like using comments, meaningful variable names, and modular code. We’ll cover these below.</p>
</li>
<li><p>Test the script: Test the script in a controlled environment to ensure it performs as expected without causing errors.</p>
</li>
<li><p>Execute and deploy: Run the script in its intended environment. If necessary, schedule its execution using tools like Cron (for Bash) or task schedulers.</p>
</li>
</ol>
<h2 id="heading-example-scripts">Example Scripts</h2>
<p>Now that you know the basics, let's have some practice. Assume you have around 100 files with the names “book-part-1.pdf”, “book-part-2.pdf”, …, “book-part-100.pdf”. You want to replace all the hyphens (-) in the file names with underscores (_), because the website where you're trying to upload these documents doesn’t allow you to upload files with names containing hyphens.</p>
<p>Here are scripts written in three different languages that all perform the same operation. The process looks like this:</p>
<ol>
<li><p>find all the files in a directory,</p>
</li>
<li><p>check if they contain hyphens (-) in their name, and</p>
</li>
<li><p>replace any hyphens with underscores (_).</p>
</li>
</ol>
<p>Here are the file names to start (containing hyphens):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563509852/e9b1e671-465d-43ed-a831-3034852de624.png" alt="File names with hyphen" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-bash-script">Bash Script</h3>
<p>We’ll start with a bash script. Here it is:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># Replace "-" with "_" in file names</span>
DIRECTORY=<span class="hljs-string">"/path/to/your/folder"</span>
<span class="hljs-keyword">for</span> FILE <span class="hljs-keyword">in</span> <span class="hljs-string">"<span class="hljs-variable">$DIRECTORY</span>"</span>/*; <span class="hljs-keyword">do</span>
    <span class="hljs-keyword">if</span> [[ <span class="hljs-string">"<span class="hljs-variable">$FILE</span>"</span> == *-* ]]; <span class="hljs-keyword">then</span>
        NEW_NAME=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$FILE</span>"</span> | sed <span class="hljs-string">'s/-/_/g'</span>)
        mv <span class="hljs-string">"<span class="hljs-variable">$FILE</span>"</span> <span class="hljs-string">"<span class="hljs-variable">$NEW_NAME</span>"</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"Renamed: <span class="hljs-variable">$FILE</span> -&gt; <span class="hljs-variable">$NEW_NAME</span>"</span>
    <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p>We define the directory (folder) at the top where our files reside. For each file in the directory, we check if the name contains a <code>-</code>. In such case, we create a new file name and store it in the variable <code>NEW_NAME</code> by copying the old file name using the <code>echo</code> command and replace the <code>-</code> with <code>_</code> using the <code>sed</code> command. Finally we use the move command <code>mv</code> with the old and new file names as arguments.</p>
<h3 id="heading-python-script">Python Script</h3>
<p>Next, let’s see what it would look like in Python:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-comment"># Replace "-" with "_" in file names</span>
directory = <span class="hljs-string">"/path/to/your/folder"</span>
<span class="hljs-keyword">for</span> filename <span class="hljs-keyword">in</span> os.listdir(directory):
    <span class="hljs-keyword">if</span> <span class="hljs-string">"-"</span> <span class="hljs-keyword">in</span> filename:
        old_path = os.path.join(directory, filename)
        new_filename = filename.replace(<span class="hljs-string">"-"</span>, <span class="hljs-string">"_"</span>)
        new_path = os.path.join(directory, new_filename)
        os.rename(old_path, new_path)
        print(<span class="hljs-string">f"Renamed: <span class="hljs-subst">{filename}</span> -&gt; <span class="hljs-subst">{new_filename}</span>"</span>)
</code></pre>
<p>The steps are pretty similar in Python. First, we define the directory and then iterate through each file in the directory. To find all files in the directory, we have to use the <code>listdir</code> method from the <code>os</code> package.</p>
<p>Then we check if the file name contains a <code>-</code> in the next line. In such a case, we find the current path (<code>old_path</code>) of the file by merging the directory and its file name. We can create the new file name by replacing the <code>-</code> with <code>_</code> using the <code>replace</code> method.</p>
<p>We then generate the new file path (<code>new_path</code>) in the similar way we generate the <code>old_path</code>. Finally, we call the <code>rename</code> method in <code>os</code> package with old and new file paths as arguments.</p>
<h3 id="heading-javascript-script">JavaScript Script</h3>
<p>And now let’s see how it would look in JavaScript:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> directory = <span class="hljs-string">'/path/to/your/folder'</span>;

fs.readdir(directory, <span class="hljs-function">(<span class="hljs-params">err, files</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error reading directory:'</span>, err);
        <span class="hljs-keyword">return</span>;
    }
    files.forEach(<span class="hljs-function"><span class="hljs-params">file</span> =&gt;</span> {
        <span class="hljs-keyword">if</span> (file.includes(<span class="hljs-string">'-'</span>)) {
            <span class="hljs-keyword">const</span> oldPath = path.join(directory, file);
            <span class="hljs-keyword">const</span> newFilename = file.replace(<span class="hljs-regexp">/-/g</span>, <span class="hljs-string">'_'</span>);
            <span class="hljs-keyword">const</span> newPath = path.join(directory, newFilename);
            fs.rename(oldPath, newPath, <span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
                <span class="hljs-keyword">if</span> (err) {
                    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`Error renaming <span class="hljs-subst">${file}</span>:`</span>, err);
                } <span class="hljs-keyword">else</span> {
                    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Renamed: <span class="hljs-subst">${file}</span> -&gt; <span class="hljs-subst">${newFilename}</span>`</span>);
                }
            });
        }
    });
});
</code></pre>
<p>The JavaScript implementation is somewhat similar to the Python implementation – but you’ll need to write more code. Generally, devs don’t prefer JavaScript for these kind of scripts. Most of them rely on Bash/Python. JavaScript is better-suited for browser-based automation scripts.</p>
<p>Still, let’s see what we have here. In this JavaScript code, you have to use two different packages, <code>fs</code> and <code>path</code>. We define the directory at the top, read the files in the directory using the <code>readdir</code> method from the <code>fs</code> package, and pass the directory as the argument. Along with directory, we also pass a callback function that will be executed once the files are read.</p>
<p>Inside the callback function, we loop through each file and check if the file name includes a hyphen (<code>-</code>). If it does, we find the old path using the <code>path</code> package with the directory and file names as arguments. We then construct the new file name by replacing all hyphens with underscores using the <code>replace</code> method.</p>
<p>Similar to the old path, we find the new path using the new file name as an argument. Then we use the <code>rename</code> method from the <code>fs</code> package to rename the file by passing both the old and new file names. If there are errors during renaming or reading the files in a directory, we log the error message. Otherwise, we log the success message.</p>
<h4 id="heading-how-to-run-these-scripts">How to run these scripts</h4>
<p>Ok, here’s how you can actually use these scripts:</p>
<ol>
<li><p>Replace <code>/path/to/your/folder</code> with the actual directory containing the files.</p>
</li>
<li><p>Run the script in the corresponding environment:</p>
<ul>
<li><p><strong>Bash:</strong> Save as a <code>.sh</code> file, then execute with <code>bash script.sh</code></p>
</li>
<li><p><strong>Python:</strong> Save as a <code>.py</code> file, then execute with <code>python script.py</code></p>
</li>
<li><p><strong>JavaScript:</strong> Save as a <code>.js</code> file, then execute with <code>node script.js</code></p>
</li>
</ul>
</li>
</ol>
<p>The screenshot below shows running the bash script to change the names of the files.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563774216/f31158ab-da77-4b18-8625-ee0b2522e3e6.png" alt="Change the name of files using bash script" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563640766/4aa508af-1f0e-4fad-8b2c-ac2369cbe337.png" alt="After running the script, the hyphens in file name are replaced with underscores" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-recurring-scripts">Recurring Scripts</h2>
<p>Recurring scripts are designed to execute at regular intervals, like checking a system’s status weekly, cleaning up logs, or fetching data updates. These scripts typically use some form of task scheduler.</p>
<h3 id="heading-common-approaches">Common Approaches</h3>
<ol>
<li><p>CRON jobs: Most operating systems support CRON, which can trigger scripts based on a defined schedule.</p>
</li>
<li><p>Task queues: Tools like Celery (Python), Bull (Node.js), or Sidekiq (Ruby) can handle scheduled jobs with more flexibility.</p>
</li>
<li><p>Cloud schedulers: Services like AWS Lambda with EventBridge, Google Cloud Scheduler, or Azure Logic Apps allow you to set up recurring scripts in a serverless architecture.</p>
</li>
</ol>
<p>One good example use case for recurring scripts would be sending a daily/weekly report of your system’s usage/performance. You could write a script that finds the number of users who have joined and subscribed to your product and send that report as an email every day/week.</p>
<h2 id="heading-best-practices-for-writing-scripts">Best Practices for Writing Scripts</h2>
<p>Here are some things to keep in mind when you’re writing scripts:</p>
<p><strong>1. Use comments</strong>: Explain complex parts of the script with comments.</p>
<p>In the below example, without the comment, someone might have to spend extra time figuring out why the tax rate is a decimal and not a percentage.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Calculate the total price with tax</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">calculate_price_with_tax</span>(<span class="hljs-params">price, tax_rate</span>):</span>
    <span class="hljs-comment"># Tax rate is expressed as a decimal (e.g., 0.07 for 7%)</span>
    <span class="hljs-keyword">return</span> price + (price * tax_rate)
</code></pre>
<p>2. <strong>Error handling</strong>: Account for possible errors and handle them gracefully.</p>
<p>In the below example, if the file is missing, the script won’t crash – instead, it will show a helpful error message.</p>
<pre><code class="lang-python"><span class="hljs-keyword">try</span>:
    <span class="hljs-keyword">with</span> open(<span class="hljs-string">'data.csv'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file:
        data = file.readlines()
<span class="hljs-keyword">except</span> FileNotFoundError:
    print(<span class="hljs-string">"Error: 'data.csv' file not found. Make sure the file exists before running the script."</span>)
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
    print(<span class="hljs-string">f"An unexpected error occurred: <span class="hljs-subst">{e}</span>"</span>)
</code></pre>
<p>3. <strong>Modular design</strong>: Break down the script into reusable functions or modules.</p>
<p>In the below example, by separating functionality into smaller, reusable functions, you can debug or reuse parts of the script independently.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fetch_data_from_api</span>(<span class="hljs-params">api_url</span>):</span>
    <span class="hljs-comment"># Fetch data from the given API</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">process_data</span>(<span class="hljs-params">data</span>):</span>
    <span class="hljs-comment"># Process the data into the desired format</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">save_to_file</span>(<span class="hljs-params">data, filename</span>):</span>
    <span class="hljs-comment"># Save processed data to a file</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-comment"># Main script</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    data = fetch_data_from_api(<span class="hljs-string">"https://example.com/api"</span>)
    processed_data = process_data(data)
    save_to_file(processed_data, <span class="hljs-string">"output.json"</span>)
</code></pre>
<p>4. <strong>Input validation</strong>: Validate user inputs to prevent unexpected errors or security risks.</p>
<p>Without validation, someone could input invalid or malicious data (for example, SQL injection strings in certain scenarios).</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> re

<span class="hljs-comment"># Validate that the input is a valid email address</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">validate_email</span>(<span class="hljs-params">email</span>):</span>
    pattern = <span class="hljs-string">r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> re.match(pattern, email):
        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Invalid email address format"</span>)
    <span class="hljs-keyword">return</span> email

<span class="hljs-comment"># Example usage</span>
<span class="hljs-keyword">try</span>:
    user_email = validate_email(input(<span class="hljs-string">"Enter your email: "</span>))
    print(<span class="hljs-string">f"Valid email: <span class="hljs-subst">{user_email}</span>"</span>)
<span class="hljs-keyword">except</span> ValueError <span class="hljs-keyword">as</span> e:
    print(e)
</code></pre>
<p>5. <strong>Version control</strong>: Use Git or other version control tools to track changes.</p>
<p>If a change breaks the script, you can easily revert to a previous commit using <code>git checkout</code>. Plus, you can collaborate seamlessly with team members.</p>
<pre><code class="lang-bash">git init
git add script.py
git commit -m <span class="hljs-string">"Initial commit"</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Writing scripts is a skill that can significantly boost your productivity and problem-solving abilities. By understanding the basics of scripting languages like Bash, Python, and JavaScript, you can automate tasks, streamline workflows, and save valuable time. Start small, build incrementally, and practice writing scripts for different use cases to master this invaluable skill.</p>
<p>I have an exercise for you. To run and verify this example script, you may think you have to manually create 100 files. That consumes a lot of time.</p>
<p>I wrote a script to generate those 100 files. I would also recommend that you try writing a script to generate 100 files with hyphens in their file names. Then try to run the example script to convert the hyphens to underscores.</p>
<p>This may sound difficult at the beginning, but believe me you just need to write 5 lines of bash code to generate 100 files. Not just 100 – you can even generate a million/billion/trillion files with just 5 lines of code.</p>
<p>If you wish to learn more about Scripts, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_what_are_scripts">email newsletter (https://5minslearn.gogosoon.com/)</a> and follow me on social media.</p>
<p>Happy scripting!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Automate Branch-Specific Netlify Configurations with a Bash Script: A Step-by-Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ When you’re working on a project with multiple environments – like staging and production – for your backend APIs and frontend deployments, you’ll want to make sure you have the correct configuration and commands for each branch in your repository. T... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-automate-branch-specific-netlify-configurations-with-a-bash-script/</link>
                <guid isPermaLink="false">6760688b00f110abd3d0f655</guid>
                
                    <category>
                        <![CDATA[ Continuous Integration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Netlify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Francis Ihejirika ]]>
                </dc:creator>
                <pubDate>Mon, 16 Dec 2024 17:51:07 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733871988108/cde4ea9b-705c-40e0-9730-09dbeebdfbae.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When you’re working on a project with multiple environments – like staging and production – for your backend APIs and frontend deployments, you’ll want to make sure you have the correct configuration and commands for each branch in your repository.</p>
<p>This can be daunting in situations where multiple developers are actively working on a codebase, making changes to different branches, or managing multiple branch-specific configurations.</p>
<p>Like with every pull request or change pushed to a branch, you’ll need to review every line of code that’s been changed, added, or removed before deciding what gets merged or not. Configuration files in codebases are not exempt from this, making them prone to errors, as a simple change can affect your entire Continuous Integration setup.</p>
<p>When changes get made to the staging or production branch and a build is triggered, you’ll want to ensure that the correct resources attached to a branch are maintained. In some cases, you may need to define different redirect rules for each respective client, custom build commands, or other settings for each branch.</p>
<p>In this article, I’ll walk through how to manage branch-specific configurations including redirects for multiple branches automatically, using a simple bash script. I’ll also show you how to safely merge context-specific rules for your staging and production branches on Netlify.</p>
<h2 id="heading-what-well-cover">What we’ll cover:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-project-structure-and-scenario">Project Structure and Scenario</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-redirectsrewrites">What are Redirects/Rewrites?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-netlify-processes-redirects">How Netlify Processes Redirects</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-using-the-redirects-file-syntax">Using the _redirects file syntax</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-using-the-netlifytoml-configuration-file-syntax">Using the netlify.toml configuration file syntax</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-problem-managing-multiple-netlifytoml-files-for-different-branches">The Problem: Managing Multiple netlify.toml Files for Different Branches</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-write-the-script-to-automatically-create-our-configuration-files">How to Write the Script to Automatically Create Our Configuration File(s)</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-sample-netlifytoml-file">Sample Netlify.toml file</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-1-create-the-script-folder-and-add-the-script-file">Step 1: Create the script folder and add the script file</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-modify-packagejson-to-include-the-script-command">Step 2: Modify package.json to include the script command</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-our-client-to-netlify">How to Deploy Our Client to Netlify</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-first-deployment-of-your-project-to-netlify">First deployment of your project to Netlify</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-subsequent-deployments-how-to-set-up-branch-deployments">Subsequent Deployments / How to Set Up Branch Deployments</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-set-up-environment-variables-in-netlify-for-each-branch-context-production-staging-and-so-on">Step 1: Set Up Environment Variables in Netlify for each branch context — production, staging, and so on</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-trigger-a-new-deploy">Step 2: Trigger a new deploy</a></p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-inspect-your-deployments">Inspect Your Deployments</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-project-structure-and-scenario">Project Structure and Scenario</h2>
<p>Consider a situation where you have two separate servers deployed for a project: one to serve requests to a staging environment (deployed to Render), and another to the production environment (deployed to Google Cloud Run).</p>
<p>You also have two separate client deployments on Netlify, each with their respective API_BASE_URLs, that are served by their respective servers as illustrated below:</p>
<p><img src="https://cdn-images-1.medium.com/max/1200/1*Zat3jiq5BCucEzDHKp8yuA.png" alt="Illustration showing branches of a project repository - development, staging and production - each with its own server and client" width="600" height="400" loading="lazy"></p>
<p>The image below is a <code>sample-project</code> repository, with <code>api</code> and <code>client</code> folders/directories within it. This is an overview of the structure in each of the branches outlined above. Each directory contains its own <code>package.json</code> file, is treated as an independent component, and can be deployed to two separate services.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*Vkh8EyIA5qamhoJOz2ksSg.png" alt="A project structure for a sample project, including directories and files for both backend and frontend. " width="600" height="400" loading="lazy"></p>
<p>In your frontend deployment for each of the clients, all your requests made to endpoints that begin with <code>/api/v1/</code> are routed to the server. Other routes remain within the frontend to direct you to pages within the client. So you’re required to write the correct rules to guide your client on how to process these requests. These are called redirect rules or rewrites.</p>
<h2 id="heading-what-are-redirectsrewrites">What are Redirects/Rewrites?</h2>
<p>Redirects, or rewrites, are rules you can create to have certain URLs automatically go to a new location anywhere on the internet (source: <a target="_blank" href="https://wpengine.com/">WPengine</a>). These are also generally known as <strong>URL forwarding</strong> and you can use them anywhere – in entire websites, sections of a website, or an entire web application.</p>
<p>In web applications, redirects are often utilized to determine how to process requests. Web hosting platforms such as Netlify and Vercel use them as well, giving developers the option to determine how their web applications process requests.</p>
<h2 id="heading-how-netlify-processes-redirects">How Netlify Processes Redirects</h2>
<p>Netlify has two possible ways to specify redirect rules. You can do it using the <code>_redirects</code> file syntax or using the <code>netlify.toml</code> configuration file syntax. They achieve the same goal, but the <code>netlify.toml</code> syntax gives you more options and capabilities.</p>
<h3 id="heading-using-the-redirects-file-syntax">Using the <code>_redirects</code> file syntax</h3>
<p>If you opt to use the redirect syntax, you should simply create a <code>_redirects</code> file in the public folder of your client app, and specify the redirect rules within it. That’s as easy as it gets. Below is an example of a redirect rule within the file:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733944577546/2f21a9b9-6843-4900-a6fe-5573a087b3d9.png" alt="Sample Netlify _redirects file showing usage syntax and redirect rules" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The above rule can be interpreted as:</p>
<ol>
<li><p>Send all my requests that match <code>/api/v1</code> to the API URL specified, and return a 200 success status code. The asterisks (*) after <code>/api/v1/</code> as seen in <code>/api/v1/*</code> instruct it to append any other extension of the original URL to the stated API URL. For example, if you have a <code>/api/v1/users</code> route in your frontend, that request will be redirected to <code>https://your-api-base-url.com/api/v1/users</code>. The <code>:splat</code> seen in the API URL is simply a placeholder.</p>
</li>
<li><p>Serve all other default routes through the index.html folder. This is required to ensure that you don’t encounter broken pages when you navigate to other pages and attempt to visit the previous page using the “back” button.</p>
</li>
</ol>
<h3 id="heading-using-the-netlifytoml-configuration-file-syntax">Using the <code>netlify.toml</code> configuration file syntax</h3>
<p>The <code>netlify.toml</code> configuration file gives you a lot more flexibility when specifying redirect rules, including but not limited to matching the original request route, the required destination, the preferred status code response, header rules, signatures, country restrictions, roles and more.</p>
<p>This is a sample <code>netlify.toml</code> file sourced from <a target="_blank" href="https://docs.netlify.com/routing/redirects/#syntax-for-the-netlify-configuration-file">Netlify’s documentation</a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733947216566/f64670b4-9d28-4c50-a753-1deb27dfc646.png" alt="Sample netlify.toml file showing configuration" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p><strong>Quick Note:</strong> using the redirects file for redirecting certain requests to our API is perfectly fine. But it can be considered a security risk adding our API URL in plain text in the <em>redirects</em> file if the API_BASE_URL is supposed to be private. This is because any file in the public folder is what it sounds like – public – and anyone can access it.</p>
<p>If the direct locations you desire to have in your app are public URLs, then feel free to utilize the <code>_redirects</code> file syntax. But if you prefer to have a private URL(s), utilizing a <code>netlify.toml</code> configuration file in combination with the environment variables is generally a better idea.</p>
<h2 id="heading-the-problem-managing-multiple-netlifytoml-files-for-different-branches">The Problem: Managing Multiple <code>netlify.toml</code> Files for Different Branches</h2>
<p>When you use the <code>netlify.toml</code> file to define your build commands and environment-specific settings, and you make changes that are pushed to your repository and open pull requests, you have to manually ignore or edit each <code>netlify.toml</code>in each branch. This eventually becomes very stressful and susceptible to errors.</p>
<p>In addition to this, we want to avoid having our API URLs hardcoded in either our <code>_redirects</code> or <code>netlify.toml</code>file within our project codebase for security reasons. We will use environment variables as provided within our Netlify UI for production and staging contexts.</p>
<p>To avoid the above problems, we will use a small script in our codebase to dynamically generate the correct <code>netlify.toml</code> files for each branch. This approach eliminates conflicts and removes the need for manual intervention when switching between branches or handling pull requests.</p>
<h2 id="heading-how-to-write-the-script-to-automatically-create-our-configuration-files">How to Write the Script to Automatically Create Our Configuration File(s)</h2>
<h3 id="heading-sample-netlifytoml-file">Sample <code>Netlify.toml</code> file</h3>
<p>Below is a screenshot of a sample <code>netlify.toml</code> file we are trying to achieve for each build. You can see that all our requests that match <code>api/v1/</code> in our codebase will be routed to our API.</p>
<p>You could have your API endpoint requests structured differently, for example <code>/api/your-endpoint</code> – just make sure to adjust the script accordingly. In this sample project, we use <code>api/v1/your-endpoint</code> as our structure.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*oj_oJDA7lnC9we2zuQHm4w.png" alt="Netlify configuration file showing build commands and redirect rules" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-1-create-the-script-folder-and-add-the-script-file">Step 1: Create the script folder and add the script file</h3>
<p>In the <code>client</code> directory, create a <code>scripts/</code> directory and a <a target="_blank" href="http://configure-netlify.sh"><code>configure-netlify.sh</code></a> script file. You are required to do this for each branch in your repo. The content remains the same.</p>
<p>Open the <a target="_blank" href="http://configure-netlify.sh"><code>configure-netlify.sh</code></a> script file and paste the following content within it:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Ensure API_BASE_URL is set</span>
<span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$API_BASE_URL</span>"</span> ]; <span class="hljs-keyword">then</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"Error: API_BASE_URL environment variable is not set."</span>
  <span class="hljs-built_in">exit</span> 1  <span class="hljs-comment"># Exit the script to stop the deployment</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Using API endpoint: <span class="hljs-variable">$API_BASE_URL</span>"</span>

<span class="hljs-comment"># Define the desired Netlify configuration</span>
NETLIFY_CONFIG=<span class="hljs-string">"
[build]
  command = \"npm install &amp;&amp; npm run build\"
  base = \"client\"
  publish = \"dist\"

[[redirects]]
  from = \"/api/v1/*\"
  to = \"<span class="hljs-variable">$API_BASE_URL</span>/:splat\"
  status = 200
  force = true

[[redirects]]
  from = \"/*\"
  to = \"/index.html\"
  status = 200
"</span>

<span class="hljs-comment"># Create or update the netlify.toml file</span>
<span class="hljs-keyword">if</span> [ ! -f <span class="hljs-string">"netlify.toml"</span> ]; <span class="hljs-keyword">then</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"Creating netlify.toml file..."</span>
<span class="hljs-keyword">else</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"Updating existing netlify.toml file..."</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$NETLIFY_CONFIG</span>"</span> &gt; netlify.toml

<span class="hljs-comment"># Confirm successful configuration</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"netlify.toml file has been configured successfully!"</span>
</code></pre>
<p>The script does the following:</p>
<ol>
<li><p>It checks the environment variables to ensure that the <code>API_BASE_URL</code> is set. If this isn’t set, it exits the build and causes it to fail. We did this to ensure that you don’t mistakenly create a successful deployment but with invalid URLs in production.</p>
</li>
<li><p>It then creates the content of the <code>netlify.toml</code> file as shown in the sample above. If your API endpoints use a different structure from <code>api/v1/your-endpoint</code>, you can adjust the script to fit your desired structure.</p>
</li>
<li><p>It checks if there already exists a <code>netlify.toml</code> file. If it doesn’t exist, it creates one and writes the content into it. If it exists, it updates it with the correct content during the build, using the <code>API_BASE_URL</code> set in the environment variables.</p>
</li>
</ol>
<h3 id="heading-step-2-modify-packagejson-to-include-the-script-command">Step 2: Modify <code>package.json</code> to include the script command</h3>
<p>To integrate this script with your build process, we will add a script command to the <code>package.json</code> file to call this script before running the actual build.</p>
<p>Add the <code>configure-netlify</code> command as follows: <code>"configure-netlify": "bash scripts/</code><a target="_blank" href="http://configure-netlify.sh"><code>configure-netlify.sh"</code></a> within the scripts in your <code>package.json</code> file.</p>
<p>Update your build command to run the script before running the actual build: <code>"build": "npm run configure-netlify &amp;&amp; vite build"</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*Sds0AS4Poe80pc9D9YkBvQ.png" alt="Image showing updated package.json file with custom configure-netlify command and updated build command" width="600" height="400" loading="lazy"></p>
<p>Don’t forget to save these changes and push them to your remote repository.</p>
<h2 id="heading-how-to-deploy-our-client-to-netlify">How to Deploy Our Client To Netlify</h2>
<p>When deploying our client to Netlify, we are given three options:</p>
<ol>
<li><p>importing an existing project (that is, a project that exists on a git repository service such as GitHub and GitLab),</p>
</li>
<li><p>importing from a template, or</p>
</li>
<li><p>manually deploying a static site using the Netlify drop (drag and drop) interface.</p>
</li>
</ol>
<p>For the configuration in our repository to work as expected during our build process, you’ll need to use the option that requires importing from an existing project such as GitHub. Using the drag-and-drop interface won’t work. If you must use this, then opt for the <code>_redirects</code> file syntax option to define your redirects.</p>
<h3 id="heading-first-deployment-of-your-project-to-netlify">First deployment of your project to Netlify</h3>
<p>When deploying your project for the first time, you are given the option of deploying only one branch initially. You can only add and specify other options, such as other branches, in subsequent deployments.</p>
<p>To deploy your project, take the following steps:</p>
<ol>
<li><p>Sign in to Netlify &gt; <a target="_blank" href="http://netlify.com">netlify.com</a></p>
</li>
<li><p>Click "Add new site" &gt; "Import an existing project" &gt; "Deploy with GitHub"</p>
</li>
<li><p>Click "Configure Netlify on GitHub" &gt; Search for your repository &gt; Select it</p>
</li>
<li><p>Enter a unique site name for your project</p>
</li>
<li><p>Configure deploy settings. Here you are required to select the preferred branch to deploy. For the initial deployment, we will deploy the <code>main</code> branch which we use as the production branch.</p>
<ul>
<li><p>Branch: main/master</p>
</li>
<li><p>Build command: <code>npm run build</code></p>
</li>
<li><p>Publish directory: <code>dist</code> (Select the directory where your static file lives. In this sample project, it’s exported into the <code>dist</code> directory. Some tools export into <code>build</code>)</p>
</li>
</ul>
</li>
<li><p>Enter the environment variables for your project. Don’t forget to enter your <code>API_BASE_URL</code> from your server. This is an essential requirement according to the bash script.</p>
</li>
<li><p>Click "Deploy site"</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733951997499/f329f2e6-b977-4b1f-a6ea-6b20610dc0d2.png" alt="Netlify deployment screen showing optional project build settings" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Your project should deploy correctly, and you’ll be able to see the <code>netlify.toml</code> configuration generated by the script by inspecting the deployment details at the bottom of the successful deployment page.</p>
<p>You can download this file to your local machine to see the configuration generated. It should match the sample <code>netlify.toml</code> file above. You can also test that it works using your generated site link.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733952720930/97ccee2f-e93b-4205-94fa-a8ab32dd37c2.png" alt="Netlify screen showing deploy log and static files after successful deployment" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-subsequent-deployments-how-to-set-up-branch-deployments">Subsequent Deployments / How to Set Up Branch Deployments</h2>
<h3 id="heading-step-1-set-up-environment-variables-in-netlify-for-each-branch-context-production-staging-and-so-on">Step 1: Set Up Environment Variables in Netlify for each branch context  — production, staging, and so on</h3>
<p>When your project has been deployed successfully, you can set up deployments for your staging branch. To edit the configurations, you’ll need to:</p>
<ol>
<li><p>Navigate to the list of your sites</p>
</li>
<li><p>Select your successfully deployed site</p>
</li>
<li><p>Click on “site configuration” on the left menu</p>
</li>
<li><p>Select “environment variables” &gt; click the “Add a variable” button.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733953093253/26948920-70a7-47bc-8f53-4cb19a9d8543.png" alt="Netlify site configuration page of successfully deployed site, showing environment variables" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You will be given the option of adding variables individually or importing an entire <code>.env</code> file. You can choose either option. In the image below, I’ve selected “Import from a <code>.env</code> file”.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734124727631/1bb20e6b-1232-4a79-bc18-2df2440cb641.png" alt="Environment variables screen showing options available to add a variable - using a single variable entry or multi entry from a .env file" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Seeing that our production site, deployed from the <code>main</code> branch (with the production environmental variables), has already been deployed, you’ll need to:</p>
<ol>
<li><p>Uncheck the production branch (to prevent replacing the initially deployed main branch. Be careful not to mix up your environment variables for different branches)</p>
</li>
<li><p>Select “branch deploys”</p>
</li>
<li><p>Copy and paste the content of your .env file in the input section</p>
</li>
<li><p>Don’t forget to add the <code>API_BASE_URL</code> environment variable for your staging environment</p>
</li>
</ol>
<p>Note that in selecting branch deploys, the environment variables imported here will affect all branch deploys, apart from the production branch. You can further customize your contexts by selecting a custom branch, but that’s an entirely different approach which may require you to further customize your <code>netlify.toml</code> configuration file or the bash script.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733953419262/2f62d3d6-2549-4a35-aa0b-7a02225bd630.png" alt="Environment variables screen with available contexts for deployment" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>If you decide to import each environment variable individually, you are given a similar option as seen below. Ensure that you select the correct context for each branch.</p>
<p>DON’T USE THE SAME VALUES FOR ALL CONTEXTS. As seen in the image below, selecting “<em>different value for each deploy context</em>” will allow you to define the values for each one. In this case, we define the values for branch deploys. Your initially used production variable should already exist.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*699HAdcahAzATFCDYlbqpw.png" alt="Environment variable insertion screen for single variable, showing value options for different contexts" width="600" height="400" loading="lazy"></p>
<p>When all the variables have been imported, you can inspect them to confirm that they have been correctly imported by selecting the dropdown on the right beside each variable and inspecting their values.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733954618431/66e90f42-4e3d-4c5b-95ec-a6ae03207498.png" alt="Environmental variables set for deployed web application" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-2-trigger-a-new-deploy">Step 2: Trigger a new deploy</h3>
<p>When all your environment variables have been imported for the different contexts – production and staging in this case – navigate to “deploys” on the left panel of your screen. Then hit the “Trigger deploy” button, clear the cache, and initiate a new deployment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733954838853/79685cf6-54a5-4495-8777-914fcc46950f.png" alt="79685cf6-54a5-4495-8777-914fcc46950f" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-inspect-your-deployments">Inspect Your Deployments</h2>
<p>You can confirm that your script works as expected by selecting any of the deployments and selecting the building dropdown in the “Deploy log”. You will see the command run, as well as your output and API URL for that deployment, as defined by your context.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733955355311/8268c1f3-c9cb-4b98-8094-59b7dd2d5b13.png" alt="Deploy log for successfully deployed web application, showing values logged by automation script during build" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>By following the steps in this guide, and using your script and updated commands in each branch in your repo, when you push changes then Netlify will automatically generate or update the <code>netlify.toml</code>file in each branch. This ensures that the correct configurations and environment variables for each environment are used at build time.</p>
<p>Your script remains the same across all the branches. This lets you focus on other code changes while your script handles the correct configuration for you safely and easily.</p>
<p>Push changes to any branch to see this in action.</p>
<p>Feel free to connect with me on <a target="_blank" href="https://x.com/@francisihej">Twitter</a> (@francisihej) or <a target="_blank" href="https://linkedin.com/in/francis-ihejirika">LinkedIn</a>!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Piping and Redirection in the Linux Terminal ]]>
                </title>
                <description>
                    <![CDATA[ The command line interface in Linux provides a powerful way of perfoming a range of tasks on your system. Because of its roots, Linux has many features baked into the terminal. Two of these powerful features are piping and redirection. These features... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/linux-terminal-piping-and-redirection-guide/</link>
                <guid isPermaLink="false">66c4c469bd556981b1bdc44b</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alvin ]]>
                </dc:creator>
                <pubDate>Fri, 26 Apr 2024 23:15:26 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/piping-redirection-linux.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The command line interface in Linux provides a powerful way of perfoming a range of tasks on your system. Because of its roots, Linux has many features baked into the terminal.</p>
<p>Two of these powerful features are piping and redirection. These features enable you to redirect the output and input of commands to and from other commands and files.</p>
<p>In this article, you'll learn what piping and redirection in Linux mean, followed by a deep dive into how to use these features yourself.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To fully understand this guide, you'll need to at least have:</p>
<ul>
<li>Basic <a target="_blank" href="https://www.freecodecamp.org/news/learn-the-basics-of-the-linux-operating-system">understanding of the Linux operating system</a>.</li>
<li>Basic experience working with the Linux command line. </li>
<li>Access to a Linux command line to try out the commands.</li>
</ul>
<p>Take a look at this <a target="_blank" href="https://www.freecodecamp.org/news/linux-command-line-tutorial/">Linux command line tutorial</a> if you're new or need a refresher. </p>
<h2 id="heading-what-is-piping-in-linux">What is Piping in Linux?</h2>
<p>Before we dive into the how, what does piping even mean? Piping is the act of directing the output of one Linux command as an input to another command. You can direct the standard output or standard error from one command to another using piping.</p>
<p>A simple example of piping is when you take the output of one command and use it as an input to another command. The pipe (|) metacharacter is used to achieve this.</p>
<p>If you're new to the concept of metacharacters, this is just a fancy name for characters with special meaning in the command line. There are other metacharacters in Linux aside from pipe (|). Common examples include less than (&lt;), greater than (&gt;), and ampersand (&amp;), to name a few.</p>
<h3 id="heading-the-basics-of-piping">The Basics of Piping</h3>
<p>The basic syntax of using the <code>pipe</code> command is as follows:</p>
<pre><code>command1 | command2 | command3 | ... | commandN
</code></pre><p>In the syntax above, the terminal will execute the commands from left to right. It will start with <code>command1</code>, and then the output will be input to <code>command2</code>. Outputs of <code>command2</code> will then be used as inputs of <code>command3</code> and so on. The good thing about piping is that you can chain as many commands as you'd like.</p>
<h3 id="heading-piping-examples">Piping Examples</h3>
<p>Below are several examples of using the <code>pipe</code> command to perform various tasks.</p>
<h4 id="heading-1-counting-the-number-of-files-and-directories">1. Counting the number of files and directories</h4>
<pre><code class="lang-bash">ls -l | wc -l
</code></pre>
<p>In the example above, the first section lists all the files and directories in the current directory using the <code>ls</code> command. The additional <code>-l</code> option tells the <code>ls</code> command to list the contents in a long list format. </p>
<p>The output of the <code>ls -l</code> command is then piped to the second section. The <code>wc -l</code> command counts the number of lines from the output of the <code>ls -l</code> command in the first section and prints the result to the terminal.</p>
<h4 id="heading-2-sorting-a-list-of-files-and-directories">2. Sorting a list of files and directories</h4>
<pre><code class="lang-bash">ls | sort
</code></pre>
<p>In the command above, the <code>ls</code> command will output the lists of the files and directories in the current directory. The list is then piped to the <code>sort</code> command, which sorts them alphabetically and prints the result to the terminal.</p>
<h4 id="heading-3-sort-and-display-unique-words-from-a-file">3. Sort and display unique words from a file</h4>
<pre><code class="lang-bash">cat words.txt | sort -r | uniq
</code></pre>
<p>The third example includes three separate commands connected by two pipes. The first command outputs the contents of the <code>words.txt</code> file, which contains a list of words. </p>
<p>The output is piped to the <code>sort -r</code> command, which sorts the words in reverse alphabetical order. Finally, the sorted words are piped to the <code>uniq</code> command, which removes duplicates and outputs the unique sorted words.</p>
<h3 id="heading-why-and-when-should-you-apply-command-piping-linux">Why and When Should You Apply Command Piping Linux?</h3>
<p>Piping takes more than just knowing the syntax. The syntax is pretty simple. To effectively use piping, you should understand its essence. </p>
<p>The purpose of piping is to help you chain commands, using the output of one as the input of another.</p>
<p>Piping is not meant to be a way to chain unrelated commands that you want to be executed sequentially. If you need to do that, write your commands in the terminal and separate them with semicolon (;) using the following syntax:</p>
<pre><code>command1 ; command2 ; ... ; commandN
</code></pre><h2 id="heading-what-is-redirection-in-linux">What Is Redirection in Linux?</h2>
<p>Redirection is the act of dictating where the inputs or outputs of your commands go. By default, commands receive data from standard input and then output the results in standard output.</p>
<p>One of the main areas where redirection proves useful is when working with commands and files. You can, for example, redirect the output of a command to a file instead of printing the output in the terminal. Alternatively, you can declare a certain file as an input to a command.</p>
<p>Like piping, Linux provides special characters to perform redirection. Here are important file-redirection characters in Linux and what they do:</p>
<ul>
<li><code>&gt;</code> – directs the output of a command to a given file.</li>
<li><code>&lt;</code> – directs the contents of a given file to a command.</li>
<li><code>&gt;&gt;</code> – directs the output of a command to a given file. Appends the output if the file exists and has content.</li>
<li><code>2&gt;</code> – directs error messages from a command to a given file.</li>
<li><code>2&gt;&gt;</code> – directs an error message from a command to a given file. Appends the error message if the file exists and has content.</li>
<li><code>&amp;&gt;</code> – directs standard output and error to a given file.</li>
<li><code>&amp;&gt;&gt;</code> – directs standard output and error to a given file. Appends to the file if it exists and has contents.</li>
</ul>
<p>Let's look at each file-redirection character in-depth.</p>
<h3 id="heading-1-output-redirection-with-gt">1. Output Redirection With <code>&gt;</code></h3>
<p>The <code>&gt;</code> symbol enables you to redirect the output of a command to a certain file. Using the symbol, you can redirect the output to any existing file. If it doesn't exist, the output redirection character will automatically create a new one. </p>
<p>However, you should be careful when writing to an existing file because its contents will be overwritten without a warning.</p>
<p>You can perform output redirection using the following syntax:</p>
<pre><code>command &gt; file
</code></pre><p>The output of running <code>command</code> will be written to the <code>file</code> instead of the standard output (or, in other words, printed to the terminal). Here's an example of how you can do output redirection:</p>
<pre><code class="lang-bash">ls -a &gt; contents.txt
</code></pre>
<p>In the command above, the list of items in the current directory (including dotfiles, directories, and files) will be written to the <code>contents.txt</code> file. You won't see any output in the terminal due to the redirection.</p>
<h3 id="heading-2-output-redirection-with-gtgt">2. Output Redirection With <code>&gt;&gt;</code></h3>
<p><code>&gt;&gt;</code> lets you redirect the output of a command to a file. But, unlike using a single greater than character (<code>&gt;</code>), <code>&gt;&gt;</code> will append the output if you try to write to an existing file (instead of overwriting its contents). If the file doesn't exist, it will create a new one.</p>
<p>The syntax is as follows:</p>
<pre><code>command &gt;&gt; file
</code></pre><p>Here's an example of using output redirection with <code>&gt;&gt;</code> to perform the same action as before:</p>
<pre><code class="lang-bash">ls -a &gt;&gt; contents.txt
</code></pre>
<h3 id="heading-3-input-redirection-with-lt">3. Input Redirection With <code>&lt;</code></h3>
<p>The <code>&lt;</code> character in the command line lets you redirect the input to a command from a file instead of the keyboard. The syntax of input redirection using <code>&lt;</code> is as follows:</p>
<pre><code>command &lt; file
</code></pre><p>Here's an example of using input redirection:</p>
<pre><code class="lang-bash">wc -w &lt; files.txt
</code></pre>
<p>In the example above, we're passing <code>files.txt</code> as the input to the <code>wc -w</code> command, which counts the number of words in the file. But you don't need to use the input redirection character in many scenarios because it's the default behavior. For instance, the command above is similar to the following:</p>
<pre><code class="lang-bash">wc -w files.txt
</code></pre>
<h3 id="heading-4-error-redirection-with-2gt-and-2gtgt">4. Error Redirection With <code>2&gt;</code> and <code>2&gt;&gt;</code></h3>
<p>When working on the command line, you may run into errors. For instance, if you want to execute a file without appropriate permissions. Instead of letting the terminal throw an error by printing it, you can use the error redirection character to dictate where the error message should go.</p>
<p>A good place to redirect errors is a file dedicated to storing errors. Here's a simple example of a command trying to access the list of files in a directory that doesn't exist:</p>
<pre><code class="lang-bash">ls nonexistent 2&gt; error.txt
</code></pre>
<p>In the example above, the terminal will throw an error since there's no file named <code>nonexistent</code>. But instead of printing it to the console, it will be stored in the <code>error.txt</code> file due to the error redirection character. However, the file will have nothing if there's no error.</p>
<p>If you must append an error to an existing file instead of overwriting its contents, use <code>2&gt;&gt;</code> instead of <code>2&gt;</code>.</p>
<h3 id="heading-5-output-and-error-redirection-with-ampgt-and-ampgtgt">5. Output and Error Redirection With <code>&amp;&gt;</code> and <code>&amp;&gt;&gt;</code></h3>
<p>Instead of choosing whether to redirect standard output or standard errors to a file, <code>&amp;&gt;</code> allows you to redirect both simultaneously. You can think of <code>&amp;&gt;</code> as a shorthand for combining the output redirection (&gt;) and error redirection (2&gt;) characters.</p>
<p>The syntax of using <code>&amp;&gt;</code> is as follows:</p>
<pre><code>command &amp;&gt; output.txt
</code></pre><p>The error or output of the <code>command</code> is written to the <code>output.txt</code> file. Here's an example:</p>
<pre><code class="lang-bash">ls sample &amp;&gt; output.txt
</code></pre>
<p>In the command above, if the <code>sample</code> directory is not available or is available but you don't have read permissions, an appropriate error will be written in the <code>output.txt</code> file. But if it exists and you have read permissions, its contents will be output in the <code>output.txt</code> file.</p>
<p>Using <code>&amp;&gt;&gt;</code> allows you to append the output to the file if it exists and has contents.</p>
<h2 id="heading-how-to-combine-piping-and-redirection-to-unleash-the-power-of-the-command-line">How to Combine Piping and Redirection to Unleash the Power of the Command Line</h2>
<p>Using piping and redirection in combination can let you perform complex operations without heavy lifting. By learning how to combine the two, you can create complex commands to perform various actions with less typing. </p>
<p>Take the following command as an example:</p>
<pre><code class="lang-bash">ls | grep <span class="hljs-string">".txt"</span> &gt; text_files.txt
</code></pre>
<p>The <code>ls</code> command lists the contents of the current directory. The output is piped to the <code>grep</code> command to filter text files. Finally, the output of the <code>grep</code> command is redirected to the <code>text_files.txt</code> file. </p>
<p>This simple yet powerful example shows that when it comes to piping and redirection, the only limit is your mind.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned the basics of piping and redirection in Linux. We covered the basics together with examples of how you can use the two. </p>
<p>The two features in isolation can be powerful, but you can go further by combining them in your commands, as shown in the last section.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Practical Guide to Regular Expressions – Learn RegEx with Real Life Examples ]]>
                </title>
                <description>
                    <![CDATA[ What are Regular Expressions? Regular expressions, also known as regex, work by defining patterns that you can use to search for certain characters or words inside strings. Once you define the pattern you want to use, you can make edits, delete certa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/practical-regex-guide-with-real-life-examples/</link>
                <guid isPermaLink="false">66ba2e427787ec7052709309</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Regular Expressions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Scripting ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tasnim Ferdous ]]>
                </dc:creator>
                <pubDate>Tue, 01 Aug 2023 20:42:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/The-Most-concise-guide-with-real-life-examples.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-what-are-regular-expressions">What are Regular Expressions?</h2>
<p>Regular expressions, also known as regex, work by defining patterns that you can use to search for certain characters or words inside strings.</p>
<p>Once you define the pattern you want to use, you can make edits, delete certain characters or words, substitute one thing for another, extract relevant information from a file or any string that contains that particular pattern, and so on.</p>
<h3 id="heading-why-should-you-learn-regex">Why Should You Learn Regex?</h3>
<p>Regex let you to do text processing in a way that can save you a lot of time. It can also introduce some fun in the process.</p>
<p>Using regex can make locating information much easier. Once you find your target, you can batch edit/replate/delete or whatever processing you need to do.</p>
<p>Some practical examples of using regex are batch file renaming, parsing logs, validating forms, making mass edits in a codebase, and recursive search.</p>
<p>In this tutorial, we're going to cover regex basics with the help of this <a href="https://regexr.com/" target="_blank">site</a>. Later on, I will introduce some regex challenges that you'll solve using Python. I'll also show you how to use tools like <code>sed</code> and <code>grep</code> with regex.</p>
<p>Like many things in life, regular expressions are one of those things that you can only truly understand by doing. I encourage you to play around with regex as you are going through this article.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>

<ul>
<li><a class="post-section-overview" href="#regex-basics">Regex Basics</a><ul>
<li><a class="post-section-overview" href="#exact-match">Exact match</a></li>
<li><a class="post-section-overview" href="#character-set">Character set</a><ul>
<li><a class="post-section-overview" href="#match-ranges-in-regex">Match ranges in regex</a></li>
<li><a class="post-section-overview" href="#match-any-character-not-in-the-set">Match any character not in the set</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#character-classes">Character classes</a></li>
<li><a class="post-section-overview" href="#heading-quantifiers">Quantifiers</a></li>
<li><a class="post-section-overview" href="#capture-groups">Capture groups</a><ul>
<li><a class="post-section-overview" href="#how-to-use-logical-or-in-regex">How to use logical OR in regex</a></li>
<li><a class="post-section-overview" href="#how-to-reference-capture-groups">How to reference capture groups</a></li>
<li><a class="post-section-overview" href="#how-to-name-capture-groups">How to name capture groups</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="post-section-overview" href="#how-to-use-regex-with-command-line-tools">How to use regex with command line tools</a><ul>
<li><a class="post-section-overview" href="#recursive-regex-search-with-grep">Recursive regex search with grep</a></li>
<li><a class="post-section-overview" href="#substitution-with-sed">Substitution with sed</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#lookarounds">Advanced Regex: Lookarounds</a><ul>
<li><a class="post-section-overview" href="#heading-lookbehinds">Lookbehinds</a></li>
<li><a class="post-section-overview" href="#heading-lookaheads">Lookaheads</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#practical-examples-of-regex">Practical Examples of Regex</a><ul>
<li><a class="post-section-overview" href="#logs-parsing">Logs parsing</a></li>
<li><a class="post-section-overview" href="#bulk-file-renaming">Bulk File Renaming</a></li>
<li><a class="post-section-overview" href="#email-validation">Email validation</a></li>
<li><a class="post-section-overview" href="#password-constraints">Password constraints</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#final-words">Final words</a></li>
</ul>

<p><a></a></p>
<h2 id="heading-regex-basics">Regex Basics</h2>
<p>A regular expression is nothing but a sequence of characters that match a pattern. Besides using literal characters (like 'abc'), there are some meta characters (*,+,? and so on) which have special purposes. There are also features like character classes which can help you simplify your regular expressions. </p>
<p>Before writing any regex, you'll need to learn about all the basic cases and edge cases for the pattern you are looking for. </p>
<p>For instance, if you want to match 'Hello World', do you want the line to start with 'Hello' or can it start with anything? Do you want exactly one space between 'Hello' and 'World' or there can be more? Can other characters come after 'World' or should the line end there? Do you care about case sensitivity? And so on.</p>
<p>These are the kind of questions you must have the answer to before you sit down to write your regex.</p>
<p><a></a></p>
<h3 id="heading-exact-match">Exact match</h3>
<p>The most basic form of regex involves matching a sequence of characters in a similar way as you can do with Ctrl-F in a text editor.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/exact_match.png" alt="exact_match" width="600" height="400" loading="lazy"></p>
<p>On the top you can see the number of matches, and on the bottom an explanation is provided for what the regex matches character by character.</p>
<p><a></a></p>
<h3 id="heading-character-set">Character set</h3>
<p>Regex character sets allow you to match any one character from a group of characters. The group is surrounded by square brackets []. </p>
<p>For example, <code>t[ah]i</code> matches "tai" and "thi". Here 't' and 'i' are fixed but between them can occur 'a' or 'h'.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match_set.png" alt="match_set" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h4 id="heading-match-ranges-in-regex">Match ranges in regex</h4>
<p>Sometimes you may want to match a group of characters which are sequential in nature, such as any uppercase English letter. But writing all 26 letters would be quite tedious. </p>
<p>Regex solves this issue with ranges. The "-" acts as a range operator. Some valid ranges are shown below:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Range</td><td>Matches</td></tr>
</thead>
<tbody>
<tr>
<td>[A-Z]</td><td>uppercase letters</td></tr>
<tr>
<td>[a-z]</td><td>lowercase letters</td></tr>
<tr>
<td>[0-9]</td><td>Any digit</td></tr>
</tbody>
</table>
</div><p>You can also specify partial ranges, such as <code>[b-e]</code> to match any of the letters 'bcde' or <code>[3-6]</code> to match any of the numbers '3456'.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match_set_ranges-1.png" alt="match_set_ranges" width="600" height="400" loading="lazy"></p>
<p>You are not limited to specifying only one range inside a character set. You can use multiple ranges and also combine them with any other additional character(s). Here, <code>[3-6u-w;]</code> will match any of '3456uvw' or semicolon ';'.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match_set_ranges_multi-1.png" alt="match_set_ranges_multi" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h4 id="heading-match-any-character-not-in-the-set">Match any character not in the set</h4>
<p>If you prefix the set with a '^', the inverse operation will be performed. For example, <code>[^A-Z0-9]</code> will match anything except uppercase letters and digits.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match_set_not.png" alt="match_set_not" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h3 id="heading-character-classes">Character classes</h3>
<p>While writing regex, you'll need to match certain groups such as digits quite often and multiple times in the same expression as well. </p>
<p>So for example, how would you match a pattern like 'letter-digit-letter-digit'? </p>
<p>With what you've learned up until now, you can come up with <code>[a-zA-Z]-[0-9]-[a-zA-z]-[0-9]</code>. This works, but you can see how the expression can get quite messy as the pattern length gets bigger.</p>
<p>To make the expression simpler, classes have been assigned to well-defined character groups such as digits. The following table shows these classes and their equivalent expression with character sets:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Class</td><td>Matches</td><td>Equivalent expression</td></tr>
</thead>
<tbody>
<tr>
<td>.</td><td>anything except newline</td><td>[^\n\r]</td></tr>
<tr>
<td>\w</td><td>word character</td><td>[a-zA-Z0-9_]</td></tr>
<tr>
<td>\W</td><td>non-word character</td><td>[^\w]</td></tr>
<tr>
<td>\d</td><td>digits</td><td>[0-9]</td></tr>
<tr>
<td>\D</td><td>non-digits</td><td>[^\d]</td></tr>
<tr>
<td>\s</td><td>space, tab, newlines</td><td>[ \t\r\n\f]</td></tr>
<tr>
<td>\S</td><td>non whitespace characters</td><td>[^\s]</td></tr>
</tbody>
</table>
</div><p>Character classes are quite handy and make your expressions much cleaner. We will use them extensively throughout this tutorial, so you can use this table as a reference point and come back here if you forget any of the classes.</p>
<p>Most of the time, we won't care about all the positions in a pattern. The "." class saves us from writing all possible characters in a set. </p>
<p>For example, <code>t..</code> matches anything that starts with t and any two characters afterwards. This may remind you of the SQL <code>LIKE</code> operator which would use <code>t%%</code> to accomplish the same thing.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match_any.png" alt="match_any" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h3 id="heading-quantifiers">Quantifiers</h3>
<p>The word "pattern" and "repetition" go hand in hand. If you want to match a 3 digit number you can use <code>\d\d\d</code>. But what if you need to match 11 digits? You could write '\d' 11 times, but a general rule of thumb while writing regex or just doing any kind of programming is that if you find yourself repeating something more than twice, you are probably unaware of some feature. </p>
<p>In regex, you can use quantifiers for this purpose. To match 11 digits, you can simply write the expression <code>\d{11}</code>.</p>
<p>The table below lists the quantifiers you can use in regex:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Quantifier</td><td>Matches</td></tr>
</thead>
<tbody>
<tr>
<td>*</td><td>0 or more</td></tr>
<tr>
<td>?</td><td>0 or 1</td></tr>
<tr>
<td>+</td><td>1 or more</td></tr>
<tr>
<td>{n}</td><td>exactly n times</td></tr>
<tr>
<td>{n, }</td><td>n or more times</td></tr>
<tr>
<td>{n, m}</td><td>n to m times inclusive</td></tr>
</tbody>
</table>
</div><p>In this example, the expression <code>can\s+write</code> matches <code>can</code> followed by 1 or more whitespaces followed by <code>write</code>. But you can see 'canwrite' is not matched as <code>\s+</code> means at least one whitespace needs to be matched. This is useful when you are searching through text which is not trimmed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/match_multi_whitespaces.png" alt="match_multi_whitespaces" width="600" height="400" loading="lazy"></p>
<p>Can you guess what <code>can\s?write</code> will match?</p>
<p><a></a></p>
<h3 id="heading-capture-groups">Capture groups</h3>
<p>Capture groups are sub-expressions enclosed in parentheses (). You can have any number of capture groups, and even nested capture groups.</p>
<p>The expression <code>(The ){2}</code> matches 'The ' twice. But without a capture group, the expression <code>The {2}</code> would match 'The' followed by 2 spaces, as the quantifier will be applied on the space character and not on 'The ' as a group.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/capture_this.png" alt="capture_this" width="600" height="400" loading="lazy"></p>
<p>You can match any pattern inside capture groups as you would with any valid regex. Here <code>(is\s+){2}</code> matches if it finds 'is' followed by 1 or more spaces twice.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/capture_is.png" alt="capture_is" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h4 id="heading-how-to-use-logical-or-in-regex">How to use logical OR in regex</h4>
<p>You can use "|" to match multiple patterns. <code>This is (good|bad|sweet)</code> matches 'This is ' followed by any of 'good' or 'bad' or 'sweet'.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/or-1.png" alt="or" width="600" height="400" loading="lazy"></p>
<p>Again, you must understand the importance of capture groups here. Think about what the expression <code>This is good|bad|sweet</code> would match?</p>
<p> <img src="https://www.freecodecamp.org/news/content/images/2023/07/or_no_capture.png" alt="or_no_capture" width="600" height="400" loading="lazy"></p>
<p>With a capture group, <code>good|bad|sweet</code> is isolated from <code>This is</code>. But if it's not inside a capture group, the entire regex is only one group. So the expression <code>This is good|bad|sweet</code> will match if the string contains 'This is good' or 'bad' or 'sweet'.</p>
<p><a></a></p>
<h4 id="heading-how-to-reference-capture-groups">How to reference capture groups</h4>
<p>Capture groups can be referenced in the same expression or while performing replacements as you can see on the Replacement tab. </p>
<p>Most tools and languages allow you to reference the nth captured group with '\n'. In this site '$n' is used while referencing on replacement. The syntax for replacement will vary depending on the tools or language you're using. For JavaScript, for example, its '$n', while for Python its '\n'.</p>
<p>In the expression <code>(This) is \1 power</code>, 'This' is captured and then referenced with '\1', effectively matching <code>This is This power</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/refer_capture.png" alt="refer_capture" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h4 id="heading-how-to-name-capture-groups">How to name capture groups</h4>
<p>You can name your capture groups with the syntax <code>(?&lt;name&gt;pattern)</code> and backreference them in the same expression with <code>\k&lt;name&gt;</code>. </p>
<p>On replacement, referencing is done by <code>$&lt;name&gt;</code>. This is the syntax for JavaScript and can vary among languages. You can learn about the differences <a href="https://www.regular-expressions.info/named.html" target="_blank">here</a>. Also note that this feature might not be available in some languages.</p>
<p>In the expression <code>(?&lt;lang&gt;[\w+]+) is the best but \k&lt;lang&gt; .*</code>, the pattern <code>[\w+]+</code> is captured with the name 'lang' and backreferenced with <code>\k&lt;lang&gt;</code>. This pattern will match any word character or '+' character 1 or more times. The <code>.*</code> at the end of the regex matches any character 0 or more times. And finally on replacement, the referencing is done by <code>$&lt;lang&gt;</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/named_capture-1.png" alt="named_capture" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h2 id="heading-how-to-use-regex-with-command-line-tools">How to Use Regex with Command Line Tools</h2>
<p>There are good CLI tools available that let you perform regex from your terminal. These tools save you even more time as you can easily test different regex without writing code in some langauge and then compiling or interpreting it. </p>
<p>Some of the well-known tools are grep, sed, and awk. Let's look at a few examples to give you some ideas on how you can leverage these tools.</p>
<p><a></a></p>
<h3 id="heading-recursive-regex-search-with-grep">Recursive regex search with grep</h3>
<p>You can execute the power of regex through grep. Grep can search patterns in a file or perform recursive search.</p>
<p>If you are on Windows, you can install grep using winget. Run this command in powershell:</p>
<pre><code class="lang-powershell">winget install <span class="hljs-literal">-e</span> -<span class="hljs-literal">-id</span> GnuWin32.Grep
</code></pre>
<p>I will show you the solution to a challenge I created for a CTF competition at my university. </p>
<p>The file attached to the challenge is a <a href="https://github.com/renzhamin/regex-guide/blob/main/ripG.zip" target="_blank">zip file</a> that contains multiple levels of directories and a lot of files in it. The name of the competition was Coderush with flag format <code>coderush{flag is here}</code>. So you have to search for the pattern <code>coderush{.*}</code> which will match the flag format <code>coderush{any character here}</code>.</p>
<p>Unzip the file with <code>unzip ripG.zip</code> and cd into it with <code>cd ripG</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/huge_files.png" alt="huge_files" width="600" height="400" loading="lazy"></p>
<p>There are 358 directories and 8731 files. Instead of searching the pattern in the files one by one, you can employ grep like this:</p>
<pre><code class="lang-sh">grep --color -R <span class="hljs-string">"coderush{.*}"</span>
</code></pre>
<p>The "-R" flag enables recursive search.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/grep.png" alt="recursive search with grep" width="600" height="400" loading="lazy"></p>
<p>You can learn more about grep and its command line options <a href="https://www.freecodecamp.org/news/grep-command-in-linux-usage-options-and-syntax-examples/" target="_blank">here</a></p>
<p><a></a></p>
<h3 id="heading-substitution-with-sed">Substitution with sed</h3>
<p>You can use sed to perform insertion, deletion, substitution on text files by specifying a regex. If you are on windows, you can get sed from <a href="https://github.com/mbuilov/sed-windows" target="_blank">here</a>. Or if you use WSL, tools like grep and sed will already be available.</p>
<p>This is the most common usage of sed:</p>
<pre><code class="lang-sh">sed <span class="hljs-string">'s/pattern/replacement/g'</span> filename
<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">${text}</span>"</span> | sed <span class="hljs-string">'s/pattern/replacement/g'</span>
</code></pre>
<p>Here, the option "g" is specified to replace all occurrences.</p>
<p>Some other useful options are <code>-n</code> to suppress the default behaviour of printing all lines and using p instead of g to print only the lines which are affected by the regex.</p>
<p>Let's take a look at the content of <a href="https://github.com/renzhamin/regex-guide/blob/main/texts.txt" target="_blank">texts.txt</a>.</p>
<pre><code>Hello rand chars World <span class="hljs-number">56</span> rand chars
Henlo <span class="hljs-number">52</span> rand chars W0rld rand chars
GREP rand chars Henlo <span class="hljs-number">62</span> rand chars
Henlo <span class="hljs-number">10</span> rand chars Henlo rand chars
GREP rand chars Henlo <span class="hljs-number">45</span> rand chars
</code></pre><p>Our task is replacing <code>Henlo number</code> with <code>Hello number</code> only in the lines where "GREP" is present. So, we are searching for the pattern <code>Henlo ([0-9]+)</code> which will match 'Henlo ' followed by 1 or more digits and all the digits are captured. Then our replacement string will be <code>Hello \1</code> – the '\1' is referencing the capture group containing the digits.</p>
<p>One way to accomplish that would be using grep to grep the lines which have "GREP" present then perform the replacement with sed.</p>
<pre><code class="lang-sh">grep <span class="hljs-string">"GREP"</span> texts.txt | sed -En <span class="hljs-string">'s/Henlo ([0-9]+)/Hello \1/p'</span>
</code></pre>
<p>The "-E" option enables extended regex without which you would need to escape the parentheses.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/grep_sed.png" alt="grep_sed" width="600" height="400" loading="lazy"></p>
<p>Or you could just use sed. Use <code>/pattern/</code> to restrict substitution on only the lines where pattern is present.</p>
<pre><code class="lang-sh">sed -En <span class="hljs-string">'/GREP/ s/Henlo ([0-9]+)/Hello \1/p'</span> texts.txt
</code></pre>
<p><a></a></p>
<h2 id="heading-advanced-regex-lookarounds">Advanced Regex: Lookarounds</h2>
<p>Lookaheads and Lookbehinds (together known as lookarounds) are features of regex that allow you to check the existence of a pattern without including it in the match.</p>
<p>You can think of them as zero width assertions – they assert the existence of a pattern but do not consume any characters in the match. These are very powerful features, but they're also computationally expensive. So make sure you keep an eye on performance if you are using them often.</p>
<p><a></a></p>
<h3 id="heading-lookbehinds">Lookbehinds</h3>
<p>Let's say you want to match the word 'linux', but you have 2 conditions.</p>
<ol>
<li>The word 'GNU' must occur before 'linux' occurs. If a line contains 'linux' but doesn't have 'GNU' before it, we want to discard that line.</li>
<li>We want to match only <code>linux</code> and nothing else.</li>
</ol>
<p>We already know how to satisfy the 1st condition. <code>GNU.*</code> will match 'GNU' followed by any number of characters. Then finally we match the word <code>linux</code>. This will match all of <code>GNU-any-characters-linux</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/GNU_LINUX.png" alt="GNU_LINUX" width="600" height="400" loading="lazy"></p>
<p>But how do we prevent matching <code>GNU.*</code> while still maintaining the 1st condition?</p>
<p>That's where a positive lookbehind comes in. You can mark a capture group as a positive lookbehind by prefixing it with <code>?&lt;=</code>. In this example, the expression becomes <code>(?&lt;=GNU.*)linux</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/positive_lookbehind.png" alt="positive_lookbehind" width="600" height="400" loading="lazy"></p>
<p>Now only <code>linux</code> is matched and nothing else.</p>
<p>Note that the expressions <code>(?&lt;=GNU.*)linux</code> and <code>linux(?&lt;=GNU.*)</code> will behave exactly the same. In the 2nd expression, although <code>linux</code> is before the lookbehind, there is <code>.*</code> after 'GNU' which matches <code>linux</code>. This means it satisfies the lookbehind. </p>
<p>To make it simpler, think about the pattern without the lookbehind. The pattern <code>GNU.*</code> will match 'GNU' and anything after it, in our case matching <code>linux</code>.</p>
<p>Now we can derive a generalized statement that the expression <code>(?&lt;=C)X</code> will match the pattern X – only if pattern C came before X (and C must not be included in the match).</p>
<p>You can also reverse the 1st condition. Match lines that contains the word <code>linux</code> only if <code>GNU</code> never came before it. This is called a negative lookbehind. The prefix in this case is <code>?&lt;!</code>. The inverse of the previous expression would be <code>(?&lt;!GNU.*)linux</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/negative_lookbehind.png" alt="negative_lookbehind" width="600" height="400" loading="lazy"></p>
<p><a></a></p>
<h3 id="heading-lookaheads">Lookaheads</h3>
<p>Lookaheads are also assertions like lookbehinds, as you saw in the previous example. The only difference is that lookbehinds make an assertion before and lookaheads makes assertion after.</p>
<p>Let's say you have these two conditions:</p>
<ol>
<li>Match <code>Hello</code> only if <code>World</code> comes somewhere after it.</li>
<li>Match only Hello and nothing else.</li>
</ol>
<p>The prefix for a positive lookahead is <code>?=</code>. The expression <code>Hello(?=.*World)</code> will meet both conditions. This is similar to <code>Hello.*World</code> except that only <code>Hello</code> will be matched whereas <code>Hello.*World</code> will match 'Hello', 'World' and anything in between.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/postive_lookahead-1.png" alt="postive_lookahead" width="600" height="400" loading="lazy"></p>
<p>Similar to the example in a positive lookbehind, the expressions <code>Hello(?=.*World)</code> and <code>(?=.*World)Hello</code> are equivalent. Because the <code>.*</code> before 'World' matches <code>Hello</code>, satisfying the 1st condition.</p>
<p>A negative lookahead is just the complement of a negative lookbehind. You can use it by prefixing it with <code>?!</code>. <code>(?!World)Hello</code> will match <code>Hello</code> only if there is no <code>World</code> anywhere after it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/negative_lookahead.png" alt="negative_lookahead" width="600" height="400" loading="lazy"></p>
<p>Here is a summary of the syntax for lookarounds when you want to match the pattern X with assertion C.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Operation</td><td>RegEx</td></tr>
</thead>
<tbody>
<tr>
<td>positive lookahead</td><td><code>(?=C)X</code></td></tr>
<tr>
<td>negative lookahead</td><td><code>(?!C)X</code></td></tr>
<tr>
<td>positive lookbehind</td><td><code>(?&lt;=C)X</code></td></tr>
<tr>
<td>negative lookbehind</td><td><code>(?&lt;!C)X</code></td></tr>
</tbody>
</table>
</div><p><a></a></p>
<h2 id="heading-practical-examples-of-regex">Practical Examples of Regex</h2>
<p><a></a></p>
<h3 id="heading-logs-parsing">Logs parsing</h3>
<p>In this <a href="https://github.com/renzhamin/regex-guide/blob/main/log_train.txt" target="_blank">log file</a>, these are the lines which we care about:</p>
<pre><code>[<span class="hljs-number">1</span>/<span class="hljs-number">10000</span>] Train loss: <span class="hljs-number">11.30368</span>, Valid loss: <span class="hljs-number">8.95446</span>, <span class="hljs-attr">Elapsed_time</span>: <span class="hljs-number">7.58941</span>
[<span class="hljs-number">500</span>/<span class="hljs-number">10000</span>] Train loss: <span class="hljs-number">0.96180</span>, Valid loss: <span class="hljs-number">0.20098</span>, <span class="hljs-attr">Elapsed_time</span>: <span class="hljs-number">82.48651</span>
[<span class="hljs-number">1000</span>/<span class="hljs-number">10000</span>] Train loss: <span class="hljs-number">0.04051</span>, Valid loss: <span class="hljs-number">0.11927</span>, <span class="hljs-attr">Elapsed_time</span>: <span class="hljs-number">156.86243</span>
</code></pre><p>Our task is to extract the training loss and validation loss for purposes such as plotting loss over the epochs. We need to extract the training loss values like <code>11.30368, 0.96180, 0.04051</code> and put them in an array.</p>
<p>All the relevant values are prefixed with '<code>Train loss:</code>', so we can use this in our regex as it is. To match the float numbers we have to match some digits followed by a "<code>.</code>" and then followed by more digits. You can do this with <code>\d+\.\d+</code>. Because we want to keep track of these numbers, they should be inside a capture group.</p>
<p>As "." has special purpose in regex, when you want to match a "." character you have to escape it with a backslash. This is applicable for all characters with a special purpose. But you dont have to escape it inside a character set.</p>
<p>Putting it altogether, the expression for extracting training loss is <code>Train loss: (\d+\.\d+)</code>. We can use the same logic to extract validation loss with <code>Valid loss: (\d+\.\d+)</code>.</p>
<p>Here is one way to extract this information using Python:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> re

f = open(<span class="hljs-string">"log_train.txt"</span>, <span class="hljs-string">"r"</span>).read()

train_loss = re.findall(<span class="hljs-string">r'Train loss: (\d+\.\d+)'</span>, f)
valid_loss = re.findall(<span class="hljs-string">r'Valid loss: (\d+\.\d+)'</span>, f)

train_loss = [float(i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> train_loss]
valid_loss = [float(i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> valid_loss]

print(<span class="hljs-string">"train_loss ="</span>, train_loss)
print(<span class="hljs-string">""</span>)
print(<span class="hljs-string">"valid_loss ="</span>, valid_loss)
</code></pre>
<p>When there is one capture group, <code>re.findall</code> searches all the lines and returns the values inside the capture group in a list. </p>
<p>Any regex function only return strings, so the values are converted to floats and printed out. Then you can directly use them in another Python script as a list of floats.</p>
<p>This is the result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/extract_loss.png" alt="extract_loss" width="600" height="400" loading="lazy"></p>
<p>You could also use sed, save the output in train_losses.txt, and read from the file. First we use '/Train/' to target only the lines with 'Train' present then we are applying the same regex as before.</p>
<pre><code class="lang-sh">sed -En <span class="hljs-string">'/Train/ s/.*Train loss: ([0-9]+\.[0-9]+).*/\1/p'</span> log_train.txt | tee train_losses.txt
</code></pre>
<p>".*" is added at the start and end so that sed matches the contents of all the relevant lines. Then the entire line is replaced by the value of the capture group. The <code>tee</code> command is used to redirect the output of sed into train_losses.txt while also printing the contents in the terminal.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/extract_loss_sed.png" alt="extract_loss_sed" width="600" height="400" loading="lazy"></p>
<p>Take a moment to think about what would you need to extract the epochs. You have to extract 500 from [500/10000] for all such lines. The array should look like [1, 500, 1000, 1500, ...]. You can follow the same approach as we used for the previous example. </p>
<p>Note that if you want to match "<code>[</code>" or "<code>]</code>", you have to escape it. The answer is given <a target="_blank" href="https://github.com/renzhamin/regex-guide/blob/main/extract_epochs_array.py">here</a>.</p>
<p><a></a></p>
<h3 id="heading-bulk-file-renaming">Bulk File Renaming</h3>
<p>You have these <a href="https://github.com/renzhamin/regex-guide/tree/main/bulk-rename" target="_blank">files</a> with some random values as prefixes. You have to rename all files as 1.mp4, 2.mp4 and so on.
This is how the files were generated.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/create_files.png" alt="create_files" width="600" height="400" loading="lazy"></p>
<p>This is a common scenario where you have a list of files which have their sequence number in the name but there are also some other characters that you don't want.</p>
<p>The pattern has to match anything up to Episode then an underscore and then the number and .mp4 at the end. </p>
<p>The relevant value is the number before '.mp4' which we will put inside a capture group. <code>.*Episode_</code> will match everything up to the number. Then we can capture the number with <code>([0-9]+)</code> and also match .mp4 with <code>\.mp4</code>. </p>
<p>So the final regex is <code>.*Episode_([0-9]+)\.mp4</code>. As we want to keep the <code>.mp4</code> the replacement string will be <code>\1.mp4</code>.</p>
<p>This is one way to solve it using sed.</p>
<pre><code class="lang-sh"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> *.mp4; <span class="hljs-keyword">do</span>
    newname=$(<span class="hljs-built_in">echo</span> <span class="hljs-variable">$i</span> | sed -En <span class="hljs-string">'s/.*Episode_([0-9]+)\.mp4/\1.mp4/p'</span>)
    mv <span class="hljs-variable">$i</span> <span class="hljs-variable">$newname</span>
<span class="hljs-keyword">done</span>;ls
</code></pre>
<p>First the new name is saved in a variable and then the mv command is used to rename the file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/bulk_rename.png" alt="bulk_rename" width="600" height="400" loading="lazy"></p>
<p>Could we have just used <code>.*</code> in place of <code>.*Episode_</code> ? In this example, yes. But there might be filenames such as <code>Steins_Gate0.mp4</code> where the <code>0</code> is part of the movie name and you didn't really want to rename this file so its always better to be as specific as possible.</p>
<p>What if some files were named as "Random_Episode6.mp4"? The difference being, there is no underscore after Episode. What change will you need to make?</p>
<p>The answer is that you'll need to add a "?" after the "_" to make it optional. The regex will be <code>.*Episode_?([0-9]+)\.mp4</code>.</p>
<p><a></a></p>
<h3 id="heading-email-validation">Email validation</h3>
<p>There are all sorts of complicated regex for validating email.</p>
<p>Here is a simple one: <code>^[^@ ]+@[^@.]+\.\w+$</code>. It matches the format <code>A@B.C</code></p>
<p>The table below breaks down this pattern into smaller pieces:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Pattern</td><td>Matches</td></tr>
</thead>
<tbody>
<tr>
<td><code>^</code></td><td>start of line</td></tr>
<tr>
<td><code>[^@ ]+</code></td><td>anything except "@" and space character</td></tr>
<tr>
<td><code>@[^@.]+</code></td><td>@ followed by anything except "@" and "." characters</td></tr>
<tr>
<td><code>\.\w+</code></td><td>"." followed by word characters</td></tr>
<tr>
<td><code>$</code></td><td>end of line</td></tr>
</tbody>
</table>
</div><p><img src="https://www.freecodecamp.org/news/content/images/2023/07/email_validation.png" alt="email_validation" width="600" height="400" loading="lazy"></p>
<p>In the regexr site, you can enable the multline flag from the Flags tab in the upper right corner. The 'gm' at the end indicates that the multiline flag is enabled.</p>
<p>We can see that line 2,3,5,6 didn't match. Can you find out the reason and which part of the regex is responsible for disqualifying it?</p>
<p>The answer is given <a href="https://github.com/renzhamin/regex-guide/blob/main/email_validation.md" target="_blank">here</a></p>
<p><a></a></p>
<h3 id="heading-password-constraints">Password constraints</h3>
<p>You can also use regex to impose constraints. Here we will uncover the power of positive lookaheads. </p>
<p>Lets say we want to accept a string only if there is a digit in it. You already know how to find a digit with the '\d' class. To accomplish that, we can use <code>[^\d]*\d</code>. This will match any non-digit character 0 or more times and then match a digit. </p>
<p>We can also use the expression <code>.*\d</code> to match one digit. So if there is no digit in the string then the lookahead will fail and the none of the characters of that string will be matched, returning an empty string "". </p>
<p>When we are using a programming language, we can check if the regex returned an empty string and determine that the constraints are not satisfied.</p>
<p>We will create a regex which imposes the following criteria:</p>
<ol>
<li>Minimum 8 characters and maximum 16 characters.</li>
<li>At least one lower case letter.</li>
<li>At least one upper case letter.</li>
<li>At least one number.</li>
</ol>
<p>To achieve this, you can use positive lookaheads. This is the regex:</p>
<p><code>^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,16}$</code></p>
<p>The table below explains which part of the regex imposes which constraint:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Pattern</td><td>Imposed Constraint</td></tr>
</thead>
<tbody>
<tr>
<td><code>.{8,16}</code></td><td>min 8 and max 16 characters</td></tr>
<tr>
<td><code>(?=.*[a-z])</code></td><td>minimum one lower case letter</td></tr>
<tr>
<td><code>(?=.*[A-Z])</code></td><td>minimum one upper case letter</td></tr>
<tr>
<td><code>(?=.*\d)</code></td><td>minimum one digit</td></tr>
</tbody>
</table>
</div><p><img src="https://www.freecodecamp.org/news/content/images/2023/07/pass_constraints.png" alt="pass_constraints" width="600" height="400" loading="lazy"></p>
<p>What modification you would need for imposing at least 5 upper case letters?</p>
<p>You may think <code>(?=.*[A-Z]{5,})</code> will do the job. But this expression requires all the 5 letters to be together. A string like <code>rand-ABCDE-rand</code> will be matched but <code>0AxBCDxE0</code> will not be matched even though it has 5 upper case letters (as they are not adjacent).</p>
<p>Yet again, we have capture groups coming to the rescue. We want to match 5 uppercase letters anywhere in the string. We already know that we can match 1 uppercase letter with <code>.*[A-Z]</code>. Now we will put them inside a capture group and attach a quantifier of minimum 5. The expression will be <code>(.*[A-Z]){5,}</code>.</p>
<p>Here is the final answer:</p>
<p>In place of <code>(?=.*[A-Z])</code> you will need <code>(?=(.*[A-Z]){5,})</code>. The expression becomes <code>^(?=.*[a-z])(?=(.*[A-Z]){5,})(?=.*\d).{8,16}$</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/pass_5_upper.png" alt="pass_5_upper" width="600" height="400" loading="lazy"></p>
<p>You could also require that the password not contain certain words to enforce stronger passwords. </p>
<p>For example, we want to reject the password if contains <code>pass</code> or <code>1234</code>. Negative lookaheads is the tool for this job. The regex would be <code>^(?!.*(pass|1234)).*$</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/restrict_words-1.png" alt="restrict_words-1" width="600" height="400" loading="lazy"></p>
<p>In this regex, we put <code>pass</code> and <code>1234</code> inside a capture group and used the logical OR operator. This capture group is nested inside another capture group which is prefixed with <code>?!.*</code>. This makes it a negative lookahead that matches if there are at least 8 characters by <code>.{8,}</code> with the condition that, <code>pass</code> or <code>1234</code> can't be present anywhere in the string.</p>
<p><a></a></p>
<h2 id="heading-final-words">Final Words</h2>
<p>I hope you got a good amount of practice while going through this article. It's ok if you forget some syntax. What's important is understanding the core concepts and having a good idea of what's possible with regex. Then, if you forget a pattern, you can just google it or reference a cheatsheet. </p>
<p>The more you practice, the more you will get by without outside help. Eventually you will be able write super complex and effective regex completely offline. </p>
<p>There are already some good regex cheatsheets out there, so I wanted to create something more in-depth here that you can reference for the core concepts and common use cases. </p>
<p>If you're looking for a cheatsheet, the one from <a href="https://quickref.me/regex.html" target="_blank">QuickRef</a> is helpful. It's a good place to recall the syntax and they also provide some basic overview of regex related functions in various programming languages.</p>
<p>Most regex techniques are the same in all programming languages and tools – but certain tools might offer additional features. So do some research on the tool you are using to pick the best one for you.</p>
<p>My final suggestion would be not to force using regex just because you can. A lot of the times a regular <code>string.find()</code> is enough to get the job done. But if you live in the terminal, you really can do a lot just with regex for sure.</p>
<p>If you like this type of article, you may keep an eye on my <a href="https://blog.renzhamin.com" target="_blank">blog</a> or twitter.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Use Bash Scripting to Enhance Your Productivity ]]>
                </title>
                <description>
                    <![CDATA[ Bash scripting is an essential skill for any developer, system administrator, or power user who wants to automate repetitive tasks and make their workflow more efficient. We just published a bash scripting for beginners course on the freeCodeCamp.org... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-bash-scripting-tutorial/</link>
                <guid isPermaLink="false">66b203fe903dc07a1351665b</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 12 Apr 2023 20:52:38 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/bashscrippting.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Bash scripting is an essential skill for any developer, system administrator, or power user who wants to automate repetitive tasks and make their workflow more efficient.</p>
<p>We just published a bash scripting for beginners course on the freeCodeCamp.org YouTube channel. Herbert from Herbertech created this course.</p>
<p>In this course, you'll learn the basics of bash scripting, including how to use basic commands, write your first bash script, and use variables and positional arguments. You'll also learn about output and input redirection, test operators, if/elif/else statements, case statements, arrays, for loops, functions, and exit codes.</p>
<p>By the end of the course, you'll have a solid understanding of how to use bash scripting to automate tasks and streamline your workflow. You'll be able to write scripts that can perform complex operations, manipulate text files using AWK and SED, and handle errors using exit codes.</p>
<p>This course is perfect for beginners who are new to bash scripting or want to refresh their knowledge. The instructor has a wealth of experience in teaching programming and web development, and his teaching style is clear, concise, and easy to follow.</p>
<p>Whether you're a developer looking to automate tasks, a system administrator managing a server, or a power user looking to make your workflow more efficient, this course is an excellent way to get started with bash scripting. </p>
<p>Watch the course on <a target="_blank" href="https://www.youtube.com/watch?v=tK9Oc6AEnR4">the freeCodeCamp.org YouTube channel</a> (1-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/tK9Oc6AEnR4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Bash Scripting Tutorial – Linux Shell Script and Command Line for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ In Linux, process automation relies heavily on shell scripting. This involves creating a file containing a series of commands that can be executed together. In this article, we'll start with the basics of bash scripting which includes variables, comm... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bash-scripting-tutorial-linux-shell-script-and-command-line-for-beginners/</link>
                <guid isPermaLink="false">66adea246778e7bd69427bbc</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zaira Hira ]]>
                </dc:creator>
                <pubDate>Mon, 20 Mar 2023 17:35:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/Copy-of-Cast-a-Function-in-SQL---Convert-Char-to-Int-SQL-Server-Example.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In Linux, process automation relies heavily on shell scripting. This involves creating a file containing a series of commands that can be executed together.</p>
<p>In this article, we'll start with the basics of bash scripting which includes variables, commands, inputs/ outputs, and debugging. We'll also see examples of each along the way.</p>
<p>Let's get started. 🚀</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><a class="post-section-overview" href="#heading-pre-requisites">Pre-requisites</a></li>
<li><a class="post-section-overview" href="#heading-introduction">Introduction</a></li>
<li><a class="post-section-overview" href="#heading-definition-of-bash-scripting">Definition of Bash scripting</a></li>
<li><a class="post-section-overview" href="#heading-advantages-of-bash-scripting">Advantages of Bash scripting</a></li>
<li><a class="post-section-overview" href="#heading-overview-of-bash-shell-and-command-line-interface">Overview of Bash shell and command line interface</a></li>
<li><a class="post-section-overview" href="#heading-how-to-get-started-with-bash-scripting">How to Get Started with Bash Scripting</a></li>
<li><a class="post-section-overview" href="#how-to-run-bash-commands-from-the-command-line">How to Run Bash Commands from the Command Line</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-and-execute-bash-scripts">How to Create and Execute Bash Scripts</a></li>
<li><p><a class="post-section-overview" href="#heading-bash-scripting-basics">Bash Scripting Basics</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-comments-in-bash-scripting">Comments in bash scripting</a></p>
</li>
<li><a class="post-section-overview" href="#heading-variables-and-data-types-in-bash">Variables and data types in Bash</a></li>
<li><a class="post-section-overview" href="#heading-input-and-output-in-bash-scripts">Input and output in Bash scripts</a></li>
<li><a class="post-section-overview" href="#heading-basic-bash-commands-echo-read-etc">Basic Bash commands (echo, read, etc.)</a></li>
<li><p><a class="post-section-overview" href="#heading-conditional-statements-ifelse">Conditional statements (if/else)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-looping-and-branching-in-bash">Looping and Branching in Bash</a></p>
</li>
<li><a class="post-section-overview" href="#heading-while-loop">While loop</a></li>
<li><a class="post-section-overview" href="#heading-for-loop">For loop</a></li>
<li><a class="post-section-overview" href="#heading-case-statements">Case statements</a></li>
<li><a class="post-section-overview" href="#heading-how-to-schedule-scripts-using-cron">How to Schedule Scripts using cron</a></li>
<li><a class="post-section-overview" href="#heading-how-to-debug-and-troubleshoot-bash-scripts">How to Debug and Troubleshoot Bash Scripts</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
<li><a class="post-section-overview" href="#heading-resources-for-learning-more-about-bash-scripting">Resources for learning more about Bash scripting</a></li>
</ol>
<h2 id="heading-pre-requisites">Pre-requisites</h2>
<p>To follow along with this tutorial, you should have the following accesses:</p>
<ul>
<li>A running version of Linux with access to the command line.</li>
</ul>
<p>If you do not have Linux installed or you are just starting out, you can easily access the Linux command line through <a target="_blank" href="https://replit.com/~">Replit</a>. Replit is a browser-based IDE where you can access the bash shell in a few minutes.</p>
<p>You can also install Linux on top of your Windows system using WSL (Windows Subsystem for Linux). <a target="_blank" href="https://www.freecodecamp.org/news/how-to-install-wsl2-windows-subsystem-for-linux-2-on-windows-10/">Here</a> is a tutorial for that.</p>
<h2 id="heading-introduction">Introduction</h2>
<h3 id="heading-definition-of-bash-scripting">Definition of Bash scripting</h3>
<p>A bash script is a file containing a sequence of commands that are executed by the bash program line by line. It allows you to perform a series of actions, such as navigating to a specific directory, creating a folder, and launching a process using the command line. </p>
<p>By saving these commands in a script, you can repeat the same sequence of steps multiple times and execute them by running the script.</p>
<h3 id="heading-advantages-of-bash-scripting">Advantages of Bash scripting</h3>
<p>Bash scripting is a powerful and versatile tool for automating system administration tasks, managing system resources, and performing other routine tasks in Unix/Linux systems. Some advantages of shell scripting are:</p>
<ul>
<li><strong>Automation</strong>: Shell scripts allow you to automate repetitive tasks and processes, saving time and reducing the risk of errors that can occur with manual execution.</li>
<li><strong>Portability</strong>: Shell scripts can be run on various platforms and operating systems, including Unix, Linux, macOS, and even Windows through the use of emulators or virtual machines.</li>
<li><strong>Flexibility</strong>: Shell scripts are highly customizable and can be easily modified to suit specific requirements. They can also be combined with other programming languages or utilities to create more powerful scripts.</li>
<li><strong>Accessibility</strong>: Shell scripts are easy to write and don't require any special tools or software. They can be edited using any text editor, and most operating systems have a built-in shell interpreter.</li>
<li><strong>Integration</strong>: Shell scripts can be integrated with other tools and applications, such as databases, web servers, and cloud services, allowing for more complex automation and system management tasks.</li>
<li><strong>Debugging</strong>: Shell scripts are easy to debug, and most shells have built-in debugging and error-reporting tools that can help identify and fix issues quickly.</li>
</ul>
<h3 id="heading-overview-of-bash-shell-and-command-line-interface">Overview of Bash shell and command line interface</h3>
<p>The terms "shell" and "bash" are used interchangeably. But there is a subtle difference between the two. </p>
<p>The term "shell" refers to a program that provides a command-line interface for interacting with an operating system. Bash (Bourne-Again SHell) is one of the most commonly used Unix/Linux shells and is the default shell in many Linux distributions.</p>
<p>A shell or command-line interface looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-135.png" alt="Image" width="600" height="400" loading="lazy">
<em>The shell accepts commands from the user and displays the output</em></p>
<p>In the above output, <code>zaira@Zaira</code> is the shell prompt. When a shell is used interactively, it displays a <code>$</code> when it is waiting for a command from the user. </p>
<p>If the shell is running as root (a user with administrative rights), the prompt is changed to <code>#</code>. The superuser shell prompt looks like this:</p>
<pre><code class="lang-bash">[root@host ~]<span class="hljs-comment">#</span>
</code></pre>
<p>Although Bash is a type of shell, there are other shells available as well, such as Korn shell (ksh), C shell (csh), and Z shell (zsh). Each shell has its own syntax and set of features, but they all share the common purpose of providing a command-line interface for interacting with the operating system.</p>
<p>You can determine your shell type using the <code>ps</code> command:</p>
<pre><code class="lang-bash">ps
</code></pre>
<p>Here is the output for me:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-134.png" alt="Image" width="600" height="400" loading="lazy">
<em>Checking the shell type. I'm using bash shell</em></p>
<p>In summary, while "shell" is a broad term that refers to any program that provides a command-line interface, "Bash" is a specific type of shell that is widely used in Unix/Linux systems.</p>
<p>Note: In this tutorial, we will be using the "bash" shell.</p>
<h2 id="heading-how-to-get-started-with-bash-scripting">How to Get Started with Bash Scripting</h2>
<h3 id="heading-running-bash-commands-from-the-command-line">Running Bash commands from the command line</h3>
<p>As mentioned earlier, the shell prompt looks something like this:</p>
<pre><code class="lang-bash">[username@host ~]$
</code></pre>
<p>You can enter any command after the <code>$</code> sign and see the output on the terminal.</p>
<p>Generally, commands follow this syntax:</p>
<pre><code>command [OPTIONS] <span class="hljs-built_in">arguments</span>
</code></pre><p>Let's discuss a few basic bash commands and see their outputs. Make sure to follow along :) </p>
<ul>
<li><code>date</code>: Displays the current date</li>
</ul>
<pre><code class="lang-bash">zaira@Zaira:~/shell-tutorial$ date
Tue Mar 14 13:08:57 PKT 2023
</code></pre>
<ul>
<li><code>pwd</code>: Displays the present working directory.</li>
</ul>
<pre><code class="lang-bash">zaira@Zaira:~/shell-tutorial$ <span class="hljs-built_in">pwd</span>
/home/zaira/shell-tutorial
</code></pre>
<ul>
<li><code>ls</code>: Lists the contents of the current directory.</li>
</ul>
<pre><code class="lang-bash">zaira@Zaira:~/shell-tutorial$ ls
check_plaindrome.sh  count_odd.sh  env  <span class="hljs-built_in">log</span>  temp
</code></pre>
<ul>
<li><code>echo</code>: Prints a string of text, or value of a variable to the terminal.</li>
</ul>
<pre><code class="lang-bash">zaira@Zaira:~/shell-tutorial$ <span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello bash"</span>
Hello bash
</code></pre>
<p>You can always refer to a commands manual with the <code>man</code> command.</p>
<p>For example, the manual for <code>ls</code> looks something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-138.png" alt="Image" width="600" height="400" loading="lazy">
<em>You can see options for a command in detail using <code>man</code></em></p>
<h3 id="heading-how-to-create-and-execute-bash-scripts">How to Create and Execute Bash scripts</h3>
<h4 id="heading-script-naming-conventions">Script naming conventions</h4>
<p>By naming convention, bash scripts end with <code>.sh</code>. However, bash scripts can run perfectly fine without the <code>sh</code> extension.</p>
<h4 id="heading-adding-the-shebang">Adding the Shebang</h4>
<p>Bash scripts start with a <code>shebang</code>. Shebang is a combination of <code>bash #</code> and <code>bang !</code> followed by the bash shell path. This is the first line of the script. Shebang tells the shell to execute it via bash shell. Shebang is simply an absolute path to the bash interpreter.</p>
<p>Below is an example of the shebang statement.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
</code></pre>
<p>You can find your bash shell path (which may vary from the above) using the command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">which</span> bash
</code></pre>
<h4 id="heading-creating-our-first-bash-script">Creating our first bash script</h4>
<p>Our first script prompts the user to enter a path. In return, its contents will be listed. </p>
<p>Create a file named <code>run_all.sh</code> using the <code>vi</code> command. You can use any editor of your choice. </p>
<pre><code class="lang-bash">vi run_all.sh
</code></pre>
<p>Add the following commands in your file and save it:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Today is "</span> `date`

<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"\nenter the path to directory"</span>
<span class="hljs-built_in">read</span> the_path

<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"\n you path has the following files and folders: "</span>
ls <span class="hljs-variable">$the_path</span>
</code></pre>
<p>Let's take a deeper look at the script line by line. I am displaying the same script again, but this time with line numbers.  </p>
<pre><code class="lang-bash">  1 <span class="hljs-comment">#!/bin/bash</span>
  2 <span class="hljs-built_in">echo</span> <span class="hljs-string">"Today is "</span> `date`
  3
  4 <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"\nenter the path to directory"</span>
  5 <span class="hljs-built_in">read</span> the_path
  6
  7 <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"\n you path has the following files and folders: "</span>
  8 ls <span class="hljs-variable">$the_path</span>
</code></pre>
<ul>
<li>Line #1: The shebang (<code>#!/bin/bash</code>) points toward the bash shell path.</li>
<li>Line #2: The <code>echo</code> command is displaying the current date and time on the terminal. Note that the <code>date</code> is in backticks.</li>
<li>Line #4: We want the user to enter a valid path. </li>
<li>Line #5: The <code>read</code> command reads the input and stores it in the variable <code>the_path</code>.</li>
<li>line #8: The <code>ls</code> command takes the variable with the stored path and displays the current files and folders.</li>
</ul>
<h4 id="heading-executing-the-bash-script">Executing the bash script</h4>
<p>To make the script executable, assign execution rights to your user using this command:</p>
<pre><code class="lang-bash">chmod u+x run_all.sh
</code></pre>
<p>Here,</p>
<ul>
<li><code>chmod</code> modifies the ownership of a file for the current user :<code>u</code>.</li>
<li><code>+x</code> adds the execution rights to the current user. This means that the user who is the owner can now run the script.</li>
<li><code>run_all.sh</code> is the file we wish to run.</li>
</ul>
<p>You can run the script using any of the mentioned methods:</p>
<ul>
<li><code>sh run_all.sh</code></li>
<li><code>bash run_all.sh</code></li>
<li><code>./run_all.sh</code></li>
</ul>
<p>Let's see it running in action 🚀</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/run-script-bash-2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-bash-scripting-basics">Bash Scripting Basics</h2>
<h3 id="heading-comments-in-bash-scripting">Comments in bash scripting</h3>
<p>Comments start with a <code>#</code> in bash scripting. This means that any line that begins with a <code>#</code> is a comment and will be ignored by the interpreter. </p>
<p>Comments are very helpful in documenting the code, and it is a good practice to add them to help others understand the code. </p>
<p>These are examples of comments:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># This is an example comment</span>
<span class="hljs-comment"># Both of these lines will be ignored by the interpreter</span>
</code></pre>
<h3 id="heading-variables-and-data-types-in-bash">Variables and data types in Bash</h3>
<p>Variables let you store data. You can use variables to read, access, and manipulate data throughout your script. </p>
<p>There are no data types in Bash. In Bash, a variable is capable of storing numeric values, individual characters, or strings of characters.</p>
<p>In Bash, you can use and set the variable values in the following ways:</p>
<ol>
<li>Assign the value directly:</li>
</ol>
<pre><code class="lang-bash">country=Pakistan
</code></pre>
<ol start="2">
<li>Assign the value based on the output obtained from a program or command, using command substitution. Note that <code>$</code> is required to access an existing variable's value.</li>
</ol>
<pre><code class="lang-bash">same_country=<span class="hljs-variable">$country</span>
</code></pre>
<p>To access the variable value, append <code>$</code> to the variable name.</p>
<pre><code class="lang-bash">zaira@Zaira:~$ country=Pakistan
zaira@Zaira:~$ <span class="hljs-built_in">echo</span> <span class="hljs-variable">$country</span>
Pakistan
zaira@Zaira:~$ new_country=<span class="hljs-variable">$country</span>
zaira@Zaira:~$ <span class="hljs-built_in">echo</span> <span class="hljs-variable">$new_country</span>
Pakistan
</code></pre>
<h3 id="heading-variable-naming-conventions">Variable naming conventions</h3>
<p>In Bash scripting, the following are the variable naming conventions:</p>
<ol>
<li>Variable names should start with a letter or an underscore (<code>_</code>).</li>
<li>Variable names can contain letters, numbers, and underscores (<code>_</code>).</li>
<li>Variable names are case-sensitive.</li>
<li>Variable names should not contain spaces or special characters.</li>
<li>Use descriptive names that reflect the purpose of the variable.</li>
<li>Avoid using reserved keywords, such as <code>if</code>, <code>then</code>, <code>else</code>, <code>fi</code>, and so on as variable names.</li>
</ol>
<p>Here are some examples of valid variable names in Bash:</p>
<pre><code class="lang-bash">name
count
_var
myVar
MY_VAR
</code></pre>
<p>And here are some examples of invalid variable names:</p>
<pre><code class="lang-bash">2ndvar (variable name starts with a number)
my var (variable name contains a space)
my-var (variable name contains a hyphen)
</code></pre>
<p>Following these naming conventions helps make Bash scripts more readable and easier to maintain.</p>
<h3 id="heading-input-and-output-in-bash-scripts">Input and output in Bash scripts</h3>
<h4 id="heading-gathering-input">Gathering input</h4>
<p>In this section, we'll discuss some methods to provide input to our scripts. </p>
<ol>
<li>Reading the user input and storing it in a variable</li>
</ol>
<p>We can read the user input using the <code>read</code> command.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash </span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"What's your name?"</span> 

<span class="hljs-built_in">read</span> entered_name 

<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"\nWelcome to bash tutorial"</span> <span class="hljs-variable">$entered_name</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/name-sh.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li>Reading from a file</li>
</ol>
<p>This code reads each line from a file named <code>input.txt</code> and prints it to the terminal. We'll study while loops later in this article.</p>
<pre><code class="lang-bash"><span class="hljs-keyword">while</span> <span class="hljs-built_in">read</span> line
<span class="hljs-keyword">do</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-variable">$line</span>
<span class="hljs-keyword">done</span> &lt; input.txt
</code></pre>
<ol start="3">
<li>Command line arguments</li>
</ol>
<p>In a bash script or function, <code>$1</code> denotes the initial argument passed, <code>$2</code> denotes the second argument passed, and so forth.</p>
<p>This script takes a name as a command-line argument and prints a personalized greeting.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello, <span class="hljs-variable">$1</span>!"</span>
</code></pre>
<p>We have supplied <code>Zaira</code> as our argument to the script.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello, <span class="hljs-variable">$1</span>!"</span>
</code></pre>
<p><strong>Output:</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/name-sh-1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-displaying-output">Displaying output</h4>
<p>Here we'll discuss some methods to receive output from the scripts.</p>
<ol>
<li>Printing to the terminal:</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello, World!"</span>
</code></pre>
<p>This prints the text "Hello, World!" to the terminal.</p>
<ol start="2">
<li>Writing to a file:</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"This is some text."</span> &gt; output.txt
</code></pre>
<p>This writes the text "This is some text." to a file named <code>output.txt</code>. Note that the <code>&gt;</code>operator overwrites a file if it already has some content. </p>
<ol start="3">
<li>Appending to a file:</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"More text."</span> &gt;&gt; output.txt
</code></pre>
<p>This appends the text "More text." to the end of the file <code>output.txt</code>.</p>
<ol start="4">
<li>Redirecting output:</li>
</ol>
<pre><code class="lang-bash">ls &gt; files.txt
</code></pre>
<p>This lists the files in the current directory and writes the output to a file named <code>files.txt</code>. You can redirect output of any command to a file this way.</p>
<h3 id="heading-basic-bash-commands-echo-read-etc">Basic Bash commands (echo, read, etc.)</h3>
<p>Here is a list of some of the most commonly used bash commands:</p>
<ol>
<li><code>cd</code>: Change the directory to a different location.</li>
<li><code>ls</code>: List the contents of the current directory.</li>
<li><code>mkdir</code>: Create a new directory.</li>
<li><code>touch</code>: Create a new file.</li>
<li><code>rm</code>: Remove a file or directory.</li>
<li><code>cp</code>: Copy a file or directory.</li>
<li><code>mv</code>: Move or rename a file or directory.</li>
<li><code>echo</code>: Print text to the terminal.</li>
<li><code>cat</code>: Concatenate and print the contents of a file.</li>
<li><code>grep</code>: Search for a pattern in a file.</li>
<li><code>chmod</code>: Change the permissions of a file or directory.</li>
<li><code>sudo</code>: Run a command with administrative privileges.</li>
<li><code>df</code>: Display the amount of disk space available.</li>
<li><code>history</code>: Show a list of previously executed commands.</li>
<li><code>ps</code>: Display information about running processes.</li>
</ol>
<h3 id="heading-conditional-statements-ifelse">Conditional statements (if/else)</h3>
<p>Expressions that produce a boolean result, either true or false, are called conditions. There are several ways to evaluate conditions, including <code>if</code>, <code>if-else</code>, <code>if-elif-else</code>, and nested conditionals.</p>
<p><strong>Syntax</strong>:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">if</span> [[ condition ]];
<span class="hljs-keyword">then</span>
    statement
<span class="hljs-keyword">elif</span> [[ condition ]]; <span class="hljs-keyword">then</span>
    statement 
<span class="hljs-keyword">else</span>
    <span class="hljs-keyword">do</span> this by default
<span class="hljs-keyword">fi</span>
</code></pre>
<p>We can use logical operators such as AND <code>-a</code> and OR <code>-o</code> to make comparisons that have more significance. </p>
<pre><code class="lang-bash"><span class="hljs-keyword">if</span> [ <span class="hljs-variable">$a</span> -gt 60 -a <span class="hljs-variable">$b</span> -lt 100 ]
</code></pre>
<p>Let's see an example of a Bash script that uses <code>if</code>, <code>if-else</code>, and <code>if-elif-else</code> statements to determine if a user-inputted number is positive, negative, or zero:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Please enter a number: "</span>
<span class="hljs-built_in">read</span> num

<span class="hljs-keyword">if</span> [ <span class="hljs-variable">$num</span> -gt 0 ]; <span class="hljs-keyword">then</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$num</span> is positive"</span>
<span class="hljs-keyword">elif</span> [ <span class="hljs-variable">$num</span> -lt 0 ]; <span class="hljs-keyword">then</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$num</span> is negative"</span>
<span class="hljs-keyword">else</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$num</span> is zero"</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<p>The script first prompts the user to enter a number. Then, it uses an <code>if</code> statement to check if the number is greater than 0. If it is, the script outputs that the number is positive. If the number is not greater than 0, the script moves on to the next statement, which is an <code>if-elif</code> statement. Here, the script checks if the number is less than 0. If it is, the script outputs that the number is negative. Finally, if the number is neither greater than 0 nor less than 0, the script uses an <code>else</code> statement to output that the number is zero.</p>
<p>Seeing it in action 🚀</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/test-odd.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-looping-and-branching-in-bash">Looping and Branching in Bash</h2>
<h3 id="heading-while-loop">While loop</h3>
<p>While loops check for a condition and loop until the condition remains <code>true</code>. We need to provide a counter statement that increments the counter to control loop execution.</p>
<p>In the example below, <code>(( i += 1 ))</code> is the counter statement that increments the value of <code>i</code>. The loop will run exactly 10 times.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
i=1
<span class="hljs-keyword">while</span> [[ <span class="hljs-variable">$i</span> -le 10 ]] ; <span class="hljs-keyword">do</span>
   <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$i</span>"</span>
  (( i += 1 ))
<span class="hljs-keyword">done</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-187.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-for-loop">For loop</h3>
<p>The <code>for</code> loop, just like the <code>while</code> loop, allows you to execute statements a specific number of times. Each loop differs in its syntax and usage.</p>
<p>In the example below, the loop will iterate 5 times.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> {1..5}
<span class="hljs-keyword">do</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-variable">$i</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-186.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-case-statements">Case statements</h3>
<p>In Bash, case statements are used to compare a given value against a list of patterns and execute a block of code based on the first pattern that matches. The syntax for a case statement in Bash is as follows:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">case</span> expression <span class="hljs-keyword">in</span>
    pattern1)
        <span class="hljs-comment"># code to execute if expression matches pattern1</span>
        ;;
    pattern2)
        <span class="hljs-comment"># code to execute if expression matches pattern2</span>
        ;;
    pattern3)
        <span class="hljs-comment"># code to execute if expression matches pattern3</span>
        ;;
    *)
        <span class="hljs-comment"># code to execute if none of the above patterns match expression</span>
        ;;
<span class="hljs-keyword">esac</span>
</code></pre>
<p>Here, "expression" is the value that we want to compare, and "pattern1", "pattern2", "pattern3", and so on are the patterns that we want to compare it against. </p>
<p>The double semicolon ";;" separates each block of code to execute for each pattern. The asterisk "*" represents the default case, which executes if none of the specified patterns match the expression.</p>
<p>Let's see an example.</p>
<pre><code class="lang-bash">fruit=<span class="hljs-string">"apple"</span>

<span class="hljs-keyword">case</span> <span class="hljs-variable">$fruit</span> <span class="hljs-keyword">in</span>
    <span class="hljs-string">"apple"</span>)
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"This is a red fruit."</span>
        ;;
    <span class="hljs-string">"banana"</span>)
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"This is a yellow fruit."</span>
        ;;
    <span class="hljs-string">"orange"</span>)
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"This is an orange fruit."</span>
        ;;
    *)
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"Unknown fruit."</span>
        ;;
<span class="hljs-keyword">esac</span>
</code></pre>
<p>In this example, since the value of "fruit" is "apple", the first pattern matches, and the block of code that echoes "This is a red fruit." is executed. If the value of "fruit" were instead "banana", the second pattern would match and the block of code that echoes "This is a yellow fruit." would execute, and so on. If the value of "fruit" does not match any of the specified patterns, the default case is executed, which echoes "Unknown fruit."</p>
<h2 id="heading-how-to-schedule-scripts-using-cron">How to Schedule Scripts using cron</h2>
<p>Cron is a powerful utility for job scheduling that is available in Unix-like operating systems. By configuring cron, you can set up automated jobs to run on a daily, weekly, monthly, or specific time basis. The automation capabilities provided by cron play a crucial role in Linux system administration.</p>
<p>Below is the syntax to schedule crons:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Cron job example</span>
* * * * * sh /path/to/script.sh
</code></pre>
<p>Here, the <code>*</code>s represent minute(s) hour(s) day(s) month(s) weekday(s), respectively.</p>
<p>Below are some examples of scheduling cron jobs.</p>
<table>
<thead>
<tr>
<th>Schedule</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>0 0 <em> </em> <em></em></code></td>
<td>Run a script at midnight every day</td>
<td><code>0 0  <em> </em> /path/to/script.sh</code></td>
</tr>
<tr>
<td><code><em>/5 </em> <em> </em> <em></em></code></td>
<td>Run a script every 5 minutes</td>
<td><code>/5 <em> </em> <em> </em> /path/to/script.sh</code></td>
</tr>
<tr>
<td><code>0 6 <em> </em> 1-5</code></td>
<td>Run a script at 6 am from Monday to Friday</td>
<td><code>0 6 <em> </em> 1-5 /path/to/script.sh</code></td>
</tr>
<tr>
<td><code>0 0 1-7 <em> </em></code></td>
<td>Run a script on the first 7 days of every month</td>
<td><code>0 0 1-7 <em> </em> /path/to/script.sh</code></td>
</tr>
<tr>
<td><code>0 12 1 <em> </em></code></td>
<td>Run a script on the first day of every month at noon</td>
<td><code>0 12 1 <em> </em> /path/to/script.sh</code></td>
</tr>
</tbody>
</table>

<h4 id="heading-using-crontab">Using crontab</h4>
<p>The <code>crontab</code> utility is used to add and edit the cron jobs.</p>
<p><code>crontab -l</code> lists the already scheduled scripts for a particular user.</p>
<p>You can add and edit the cron through <code>crontab -e</code>.</p>
<p>You can read more about corn jobs in my <a target="_blank" href="https://www.freecodecamp.org/news/cron-jobs-in-linux/">other article here</a>. </p>
<h2 id="heading-how-to-debug-and-troubleshoot-bash-scripts">How to Debug and Troubleshoot Bash Scripts</h2>
<p>Debugging and troubleshooting are essential skills for any Bash scripter. While Bash scripts can be incredibly powerful, they can also be prone to errors and unexpected behavior. In this section, we will discuss some tips and techniques for debugging and troubleshooting Bash scripts.</p>
<h3 id="heading-set-the-set-x-option">Set the <code>set -x</code> option</h3>
<p>One of the most useful techniques for debugging Bash scripts is to set the <code>set -x</code> option at the beginning of the script. This option enables debugging mode, which causes Bash to print each command that it executes to the terminal, preceded by a <code>+</code> sign. This can be incredibly helpful in identifying where errors are occurring in your script.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">set</span> -x

<span class="hljs-comment"># Your script goes here</span>
</code></pre>
<h3 id="heading-check-the-exit-code">Check the exit code</h3>
<p>When Bash encounters an error, it sets an exit code that indicates the nature of the error. You can check the exit code of the most recent command using the <code>$?</code> variable. A value of <code>0</code> indicates success, while any other value indicates an error.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Your script goes here</span>

<span class="hljs-keyword">if</span> [ $? -ne 0 ]; <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"Error occurred."</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<h3 id="heading-use-echo-statements">Use <code>echo</code> statements</h3>
<p>Another useful technique for debugging Bash scripts is to insert <code>echo</code> statements throughout your code. This can help you identify where errors are occurring and what values are being passed to variables.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Your script goes here</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Value of variable x is: <span class="hljs-variable">$x</span>"</span>

<span class="hljs-comment"># More code goes here</span>
</code></pre>
<h3 id="heading-use-the-set-e-option">Use the <code>set -e</code> option</h3>
<p>If you want your script to exit immediately when any command in the script fails, you can use the <code>set -e</code> option. This option will cause Bash to exit with an error if any command in the script fails, making it easier to identify and fix errors in your script.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">set</span> -e

<span class="hljs-comment"># Your script goes here</span>
</code></pre>
<h3 id="heading-troubleshooting-crons-by-verifying-logs">Troubleshooting crons by verifying logs</h3>
<p>We can troubleshoot crons using the log files. Logs are maintained for all the scheduled jobs. You can check and verify in logs if a specific job ran as intended or not.</p>
<p>For Ubuntu/Debian, you can find <code>cron</code>logs at:</p>
<pre><code class="lang-bash">/var/<span class="hljs-built_in">log</span>/syslog
</code></pre>
<p>The location varies for other distributions.</p>
<p> A cron job log file can look like this:</p>
<pre><code class="lang-bash">2022-03-11 00:00:01 Task started
2022-03-11 00:00:02 Running script /path/to/script.sh
2022-03-11 00:00:03 Script completed successfully
2022-03-11 00:05:01 Task started
2022-03-11 00:05:02 Running script /path/to/script.sh
2022-03-11 00:05:03 Error: unable to connect to database
2022-03-11 00:05:03 Script exited with error code 1
2022-03-11 00:10:01 Task started
2022-03-11 00:10:02 Running script /path/to/script.sh
2022-03-11 00:10:03 Script completed successfully
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we started with how to access the terminal and then ran some basic bash commands. We also studied what a bash shell is. We briefly looked at branching the code using loops and conditionals. Finally, we discussed automating the scripts using cron followed by some troubleshooting techniques.</p>
<h3 id="heading-resources-for-learning-more-about-bash-scripting">Resources for learning more about Bash scripting</h3>
<p>If you want to dig deeper into the world of bash scripting, I would suggest you have a look at this 6-hour course on Linux at freeCodeCamp.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/sWbUDq4S6Y8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>What’s your favorite thing you learned from this tutorial? You can also connect with me on any of these <a target="_blank" href="https://zaira_.bio.link/">platforms</a>. 📧�</p>
<p>See you in the next tutorial, happy coding 😁</p>
<p>Banner image credits: Image by <a target="_blank" href="https://www.freepik.com/free-vector/hand-drawn-flat-design-devops-illustration_25726540.htm#query=programmer%20linux&amp;position=4&amp;from_view=search&amp;track=ais">Freepik</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Pair Programming with the ChatGPT AI – Does GPT-3.5 Understand Bash? ]]>
                </title>
                <description>
                    <![CDATA[ We've been hearing a lot about artificial intelligence and natural language processing – and in particular about the latest version of OpenAI's GPT – for weeks.  The recent release of GPT 3.5, and specifically the very new ChatGPT tool, is definitely... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/pair-programming-with-the-chatgpt-ai-how-well-does-gpt-3-5-understand-bash/</link>
                <guid isPermaLink="false">66b9961b17d9592471979c2a</guid>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Chat ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Fri, 16 Dec 2022 17:51:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/pexels-pavel-danilyuk-8438951.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>We've been hearing a lot about artificial intelligence and natural language processing – and in particular about the latest version of OpenAI's GPT – for weeks. </p>
<p>The recent release of GPT 3.5, and specifically the very new ChatGPT tool, is definitely a huge leap forward.</p>
<p>You may have read about people asking the AI to draw up real estate contracts and wills, and even generate programming code. This article approaches the tool from a slightly different perspective. </p>
<p>You can watch a video version of this article here if you'd like to use it to supplement your learning:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GxJKuINwPSw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-experimenting-with-chatgpt-and-bash-scripting">Experimenting with ChatGPT and Bash Scripting</h2>
<p>I decided to see how ChatGPT handles Linux Bash scripting. But (spoiler alert!) as I worked through the tool's suggestions - both good code and bad code - I began to realize that there was an even more powerful benefit staring me in the face: an opportunity to pair-program with an eminently helpful partner.</p>
<p>The AI ultimately failed to solve my problem, but the <em>way</em> it failed was absolutely fascinating. And watching the AI searching for new answers was absolutely crazy.</p>
<h3 id="heading-first-attempt-chatgpt-tries-to-solve-the-problem">First Attempt – ChatGPT Tries to Solve the Problem</h3>
<p>So let's see how it all happened. Here, more or less, is the initial prompt I provided to the AI:</p>
<blockquote>
<p>Write me a Bash script that prompts for the URL of a YouTube video and then uses the yt-dlp program to download from that URL. The script should then change the file name to "myvideo.mp4"</p>
</blockquote>
<p>After a few seconds, the ChatGPT told me that a script was coming. Here's how that code looked:</p>
<pre><code>#!<span class="hljs-regexp">/bin/</span>bash

# Prompt user <span class="hljs-keyword">for</span> YouTube video URL
read -p <span class="hljs-string">"Enter YouTube video URL: "</span> url

# Download video <span class="hljs-keyword">from</span> YouTube using yt-dlp
yt-dlp $url

# Get the name <span class="hljs-keyword">of</span> the downloaded video file
yt-dlp $url

# Change the downloaded video filename to <span class="hljs-string">"myvideo.mkv"</span>
mv video-filename.mp4 myvideo.mp4
</code></pre><p>The AI obviously knows what Bash scripts are and how to present code. It even did a great job commenting each line of code. The AI knows how to properly prompt the user for input and then how to import the input string into a variable called <code>url</code>. </p>
<p>It also knows about the yt-dlp program and how it works, appropriately feeding it the URL that was provided. Then it at least attempted to rename the downloaded video file to myvideo.mp4. But everything kind of broke down when it assumed that the download filename would be video-filename.mp4. Whoops.</p>
<p>At any rate, the AI helpfully showed me how to create the script from its code and then run it.</p>
<h3 id="heading-second-attempt-chatgpt-corrects-itself">Second Attempt – ChatGPT Corrects Itself</h3>
<p>My first follow-up prompt pointed out the obvious mistake and, after a few seconds, ChatGPT admitted it was wrong and offered an improvement. </p>
<blockquote>
<p>You're right, the script I provided would not work as expected because it assumes that the downloaded video will be saved to a file with the name <code>video-filename.mp4</code>. However, this is not guaranteed to be the case. To fix this...</p>
</blockquote>
<p>It's just mind-blowing how the AI is completely engaged in the process here. It remembers its first code, listens to and understands my complaint, and thinks through a solution. Here's that second attempt:</p>
<pre><code>#!<span class="hljs-regexp">/bin/</span>bash

# Prompt user <span class="hljs-keyword">for</span> YouTube video URL
read -p <span class="hljs-string">"Enter YouTube video URL: "</span> url

# Download video <span class="hljs-keyword">from</span> YouTube using yt-dlp
yt-dlp $url

# Get the name <span class="hljs-keyword">of</span> the downloaded video file
filename=$(basename $url)

# Change the downloaded video filename to <span class="hljs-string">"myvideo.mkv"</span>
mv $filename.mp4 myvideo.mp4
</code></pre><p>Ok, so I can see how the solution kind of looked right. <code>basename</code> is a Linux tool that can strip out file system directories and leave nothing but the actual filename.</p>
<p>The problem is that the variable <code>url</code> doesn't contain a local filename, but an internet address. This one definitely isn't going to work.</p>
<h3 id="heading-third-attempt-chatgpt-tries-again">Third Attempt – ChatGPT Tries Again</h3>
<p>So I tried again, explaining how that wasn't the right tool for the job. And ChatGPT gives it another try. </p>
<pre><code>#!<span class="hljs-regexp">/bin/</span>bash

# Prompt user <span class="hljs-keyword">for</span> YouTube video URL
read -p <span class="hljs-string">"Enter YouTube video URL: "</span> url

# Extract the filename <span class="hljs-keyword">from</span> the URL
filename=$(basename $url)

# Download the video using the yt-dlp tool and specify the filename
yt-dlp -o $filename $url

# Change the downloaded video filename to <span class="hljs-string">"myvideo.mkv"</span>
mv $filename.mp4 myvideo.mp4
</code></pre><p>This time, it shows that it had familiarized itself with the yt-dlp documentation, suggesting that we use the <code>-o</code> argument to give the downloading video a name, against which <code>basename</code> should now work. With each iteration, the AI gives me this updated code for my cutting and pasting pleasure.</p>
<p>Of course, that wasn't going to work either. With the next attempt, I get the feeling that the AI is a bit desperate. </p>
<h3 id="heading-if-at-first-you-dont-succeedat-least-youll-learn-something">If At First You Don't Succeed...At Least You'll Learn Something</h3>
<p>I'm going to skip past the next attempt or two, as we ran into a side problem: Videos coming from YouTube aren't always MP4s, they're sometimes MKVs or even WEBMs. That uncertainty could mess with the filenames we're working with, so I asked ChatGPT to work that into the code. </p>
<pre><code>#!<span class="hljs-regexp">/bin/</span>bash

# Prompt user <span class="hljs-keyword">for</span> YouTube video URL
read -p <span class="hljs-string">"Enter YouTube video URL: "</span> url

# Extract the filename <span class="hljs-keyword">from</span> the URL
filename=$(basename $url)

# Download the video using the yt-dlp tool and specify the filename
yt-dlp -F mp4 -O $filename $url

# Change the downloaded video filename to <span class="hljs-string">"myvideo.mkv"</span>
mv $filename.mp4 myvideo.mp4
</code></pre><p>When I reported how that, too, wouldn't work, the AI started to get confused. First it told me that the <code>-F</code> option was expecting a valid video format, but that "mp4" wasn't valid. Then it gives me valid options, including "mp4".</p>
<p>When nothing the AI suggested worked, it gave up, advising me to make sure that yt-dlp was actually installed on my machine and showing me how to do that. </p>
<p>I figured that was a good time to give up. It was a surprisingly good effort and, even if it didn't solve the problem, it did show me some useful syntax and got me thinking.</p>
<p>In case you're interested, by the way, here's how an actual working script would look. </p>
<pre><code>#!<span class="hljs-regexp">/bin/</span>bash

# Prompt user <span class="hljs-keyword">for</span> YouTube video URL
read -p <span class="hljs-string">"Enter YouTube video URL: "</span> url

# Download video <span class="hljs-keyword">from</span> YouTube using yt-dlp
yt-dlp $url

# Get the name <span class="hljs-keyword">of</span> the downloaded video file
original_filename=$(ls | awk <span class="hljs-string">'/mp4/ || /webm/ || /mkv/'</span>)

# Change the downloaded video filename to <span class="hljs-string">"myvideo.mkv"</span>
mv <span class="hljs-string">"$original_filename"</span> /home/ubuntu/vids/myvideo.mp4
</code></pre><p>The first two lines of code are just the way ChatGPT suggested. But I then isolate the filename by listing all the files in the current directory and using <code>awk</code> to filter for only filenames containing either mp4, webm, or mkv. (This assumes that there will never be more than one video file in the directory at a time.) </p>
<p>The filename will then be written to the <code>original_filename</code> variable. I'll then use that variable as part of a <code>move</code> command to rename the file <code>myvideo.mp4</code> As far as I can tell, that'll work no matter what format was actually sent.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Artificial intelligence might not be quite ready for real-world programming tasks today, but I wouldn't want to bet against it getting there tomorrow...or some time next year. </p>
<p>In the meantime though, I would absolutely recommend engaging with tools like ChatGPT whenever you're faced with a challenging programming task. </p>
<p>Two minds are (almost) always better than one.</p>
<p><em>Besides my <a target="_blank" href="https://www.youtube.com/@davidbclinton">my YouTube channel</a> (to which you can subscribe), <a target="_blank" href="https://bootstrap-it.com">my website</a> links to all kinds of technology goodness available as articles, books, and courses.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Linux Shells for Beginners – Bash, Zsh, and Fish Explained ]]>
                </title>
                <description>
                    <![CDATA[ When you open up your terminal, chances are that it uses Bash as its UNIX shell environment. But other "shell" environments exist. There are other environments such as the C Shell, Korn Shell, Z Shell, and even the Fish Shell. All of these different ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/linux-shells-explained/</link>
                <guid isPermaLink="false">66ba5e1d6345dce12bfbb0e2</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ zsh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Anthony Behery ]]>
                </dc:creator>
                <pubDate>Tue, 13 Dec 2022 21:55:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/pexels-oleksandr-pidvalnyi-320260.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When you open up your terminal, chances are that it uses Bash as its UNIX shell environment. But other "shell" environments exist.</p>
<p>There are other environments such as the C Shell, Korn Shell, Z Shell, and even the Fish Shell. All of these different shell environments have their own pros and cons, and you should consider them before you choose one to use on your own system.</p>
<p>In this article, I'll go over a few popular shells along with their main features to help you pick one.</p>
<h2 id="heading-the-bash-shell">The Bash Shell</h2>
<p>The Bash Shell (or the Bourne Again Shell) is a UNIX shell and command language. It was written by Brain Fox for the GNU Project as a free software replacement for the Bourne Shell (sh). </p>
<p>Bash was first released in 1989, and for most Linux distributions it's the default Shell environment. Other distros, like Kali Linux, use the Z Shell as their default shell. </p>
<p>Bash is one of the first programs that Linus Torvalds (the creator of Linux) ported to Linux. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/cli_example.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.geeksforgeeks.org/introduction-linux-shell-shell-scripting/">Image Source</a></em></p>
<p>Something you should not get confused about is that Bash is also a programming language. So it's a "Shell", but you can also program behavior in Bash. For example:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello World"</span>
</code></pre>
<h3 id="heading-key-points-about-bash">Key points about Bash</h3>
<ul>
<li>Most users use Bash, since it is the default shell environment on most systems</li>
<li>Bash does not have an inline wildcard expression. A wildcard expression is when you would want to search for patterns in your Shell, similar to Regex. The three main wildcards are <code>*</code>, <code>?</code>, and <code>[]</code>.</li>
<li>You can't automatically change the directory name</li>
<li><code>#</code> is treated as a comment in scripting </li>
<li>It has <code>shopt</code> settings</li>
<li>Prompt has backslash escapes</li>
<li>User configuration settings are in <code>.bashrc</code></li>
</ul>
<h2 id="heading-the-z-shell">The Z Shell</h2>
<p>The Z Shell, or Zsh is also a UNIX shell that is very similar to Bash. You can also script and use the shell as a command interpreter. </p>
<p>Zsh is an extension of the Bourne shell with a lot of improvements. Zsh was released in 1990 by Paul Falstad, and it has some features that Bash, Korn Shell, and C Shell share. </p>
<p>macOS by default uses the Zsh Shell. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/nebirhos.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://ohmyz.sh/">Image Source</a></em></p>
<h3 id="heading-key-points-about-zsh">Key points about Zsh</h3>
<ul>
<li>Comes with autocompletion when using the terminal. So when you press <code>Tab ↹</code> in order to autocomplete whatever command you want to run, not only does it autocomplete for you but will bring down a drop-down of all the other possible files and directories:</li>
</ul>
<p><img src="https://i.ibb.co/bswYkn0/0f8c8e1a6016.gif" alt="Zsh Toggle" width="600" height="400" loading="lazy"></p>
<ul>
<li>Supports inline wildcard expressions</li>
<li>Much more configurable than Bash</li>
<li>Supports plugins and themes. Here's a <a target="_blank" href="https://github.com/unixorn/awesome-zsh-plugins">list of plugins</a> available for Zsh.</li>
</ul>
<p>There are also frameworks built around the Z Shell. One of the most popular ones is <a target="_blank" href="https://ohmyz.sh/">Oh My Zsh</a>, which is a community driven, open-source framework for managing Zsh configuration. (I use Oh My Zsh 😄) </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/oh-my-zsh-mac.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://osxdaily.com/2021/11/15/how-install-oh-my-zsh-mac/">Image Source</a></em></p>
<p>Zsh and Oh My Zsh are similar but not the same exact things. To reiterate, Oh My Zsh is a way of managing your Zsh configurations, it is not the Shell itself. </p>
<h2 id="heading-the-fish-shell">The Fish Shell</h2>
<p>Fish is a UNIX shell environment with an emphasis on interactivity and usability. Unlike Zsh, Fish aims to give the user interactivity by default instead of trusting the user to implement their own configuration.  </p>
<p>It was created by Axel Liljencrantz in 2005. Fish is considered to be an "exotic shell" due to the fact that it does not comply to the POSIX shell standards. [[Source](https://en.wikipedia.org/wiki/Fish_(Unix_shell)]</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/fish-shell-screenshot.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://blog.sudobits.com/2015/06/05/fish-a-user-friendly-command-line-shell-for-ubuntulinux/">Image Source</a></em></p>
<h3 id="heading-key-points-about-fish">Key points about Fish</h3>
<ul>
<li>Fish has "search as you type" automatic suggestions based on your command history and the directory you are in. Similar to Bash's history search, Fish Shell's search history is <strong>always</strong> turned on. That way the user will be able to get interactive feedback when working in their terminal. </li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/fish.gif" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://taskwarrior.org/news/news.20140906/">Image Source</a></em></p>
<ul>
<li>Fish also prefers features as commands rather than syntax. This makes features visible in terms of commands with options and help texts</li>
<li>Since Fish by default comes with a lot of configurations already set, it is believed to be more beginner friendly than other <code>sh</code> options like Zsh.</li>
<li>Fish's scripting language is different than Zsh and Bash. Zsh uses more aliases whereas Fish avoids using aliases in the scripting language.</li>
</ul>
<p>If you were to just make scripts using basic commands such as, <code>cd</code>, <code>cp</code>, <code>vim</code>, <code>ssh</code>, and so on, you would not notice any difference in the way Fish and Bash's scripting languages work. </p>
<p>One of the biggest differences is when you try capturing output from a command. In Bash you may be used to this:</p>
<pre><code class="lang-bash">todays_date=$(date)
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Todays date is <span class="hljs-variable">$todays_date</span>"</span>
</code></pre>
<p><img src="https://i.ibb.co/0hrF0Y3/fa71b0032fba.gif" alt="Output" width="600" height="400" loading="lazy"></p>
<pre><code>Todays <span class="hljs-built_in">Date</span> is Tue Dec <span class="hljs-number">13</span> <span class="hljs-number">15</span>:<span class="hljs-number">29</span>:<span class="hljs-number">28</span> CST <span class="hljs-number">2022</span>
</code></pre><p>Whereas in Fish, capturing output works differently. The equivalent for Fish in scripting would look like this:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">set</span> date (date)
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Todays Date <span class="hljs-variable">$date</span>"</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/ezgif.com-gif-maker.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<pre><code class="lang-bash">todays date is Tue Dec 13 21:35:03 UTC 2022
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Bash, Z Shell, and Fish Shell all have their merits, along with some similarities. You can use each of them effectively in your work environment now that you know a bit more about them. </p>
<p>If you want something more configurable, you could use Zsh (or even install Oh My Zsh). If you want more of an interactive terminal experience without a lot of configuration, you could use Fish Shell. If you want the classic feel, you can just keep Bash. </p>
<p>It all really comes down to your preferences as a developer - so just choose the shell that works best for you.</p>
<p><em>Hope this helped you! Thank you for reading</em> 🐚🐚🐚</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Bash If Statement – Linux Shell If-Else Syntax Example ]]>
                </title>
                <description>
                    <![CDATA[ When coding, you might need to make decisions based on certain conditions. Conditions are expressions that evaluate to a boolean expression (true or false). Statements that help to execute different code branches based on certain conditions are known... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bash-if-statement-linux-shell-if-else-syntax-example/</link>
                <guid isPermaLink="false">66adea216778e7bd69427bba</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zaira Hira ]]>
                </dc:creator>
                <pubDate>Mon, 14 Nov 2022 15:37:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/Copy-of-Copy-of-read-write-files-python--4-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When coding, you might need to make decisions based on certain conditions. Conditions are expressions that evaluate to a boolean expression (<code>true</code> or <code>false</code>).</p>
<p>Statements that help to execute different code branches based on certain conditions are known as conditional statements.</p>
<p><code>if...else</code> is one of the most commonly used conditional statements. Like other programming languages, Bash scripting also supports <code>if...else</code> statements. And we will study that in detail in this blog post.</p>
<h2 id="heading-syntax-of-if-statements">Syntax of <code>if</code> Statements</h2>
<p>You can use <code>if</code> statements in a variety of ways. The generic structure of <code>if</code> statements is as follows:</p>
<ul>
<li>Using an <code>if</code> statement only: <code>if...then...fi</code> </li>
<li>Using and <code>if</code> with an <code>else</code> statement: <code>if...then...else...fi</code> statements</li>
<li>Using multiple <code>else</code> statements with <code>if</code>: <code>if..elif..else..fi</code></li>
</ul>
<p>## </p>
<h2 id="heading-how-to-use-the-if-statement">How to Use the <code>if</code> Statement</h2>
<p>When you are using a single <code>if</code> statement, the syntax is as follows:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">if</span> [ condition ]
<span class="hljs-keyword">then</span>
    statement
<span class="hljs-keyword">fi</span>
</code></pre>
<blockquote>
<p>Note that the spaces are part of the syntax and should not be removed.</p>
</blockquote>
<p>Let's go through an example where we are comparing two numbers to find if the first number is the smaller one.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#! /bin/sh</span>

a=5
b=30

<span class="hljs-keyword">if</span> [ <span class="hljs-variable">$a</span> -lt <span class="hljs-variable">$b</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"a is less than b"</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<p>If you run the above snippet, the condition <code>if [ $a -lt $b ]</code> evaluates to <code>True</code> , and the statement inside the if statement executes</p>
<p><strong>Output:</strong></p>
<pre><code class="lang-bash">a is less than b
</code></pre>
<h2 id="heading-how-to-use-the-if-else-statement">How to Use the <code>if .. else</code> Statement</h2>
<p>When you are using an <code>if</code> statement and you want to add another condition, the syntax is as follows:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">if</span> [ condition ]
<span class="hljs-keyword">then</span>
    statement
<span class="hljs-keyword">else</span>
    <span class="hljs-keyword">do</span> this by default
<span class="hljs-keyword">fi</span>
</code></pre>
<p>Let's see an example where we want to find if the first number is greater or smaller than the second one. Here, <code>if [ $a -lt $b ]</code> evaluates to false, which causes the <code>else</code> part of the code to run. </p>
<pre><code class="lang-bash"><span class="hljs-meta">#! /bin/sh</span>

a=99
b=45

<span class="hljs-keyword">if</span> [ <span class="hljs-variable">$a</span> -lt <span class="hljs-variable">$b</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"a is less than b"</span>
<span class="hljs-keyword">else</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"a is greater than b"</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-bash">a is greater than b
</code></pre>
<h2 id="heading-how-to-use-ifelifelse-statements">How to Use <code>if..elif..else</code> Statements</h2>
<p>Let's say you want to add further conditions and comparisons to make the code dynamic. In this case, the syntax would look like this:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">if</span> [ condition ]
<span class="hljs-keyword">then</span>
    statement
<span class="hljs-keyword">elif</span> [ condition ] 
<span class="hljs-keyword">then</span>
    statement 
<span class="hljs-keyword">else</span>
    <span class="hljs-keyword">do</span> this by default
<span class="hljs-keyword">fi</span>
</code></pre>
<p>To create meaningful comparisons, we can use AND <code>-a</code> and OR <code>-o</code> as well.</p>
<p>In this example, we will determine the type of triangle using these conditions:</p>
<ul>
<li><code>Scalene</code>:  A triangle where every side is different in length.</li>
<li><code>Isosceles</code>: A triangle where 2 sides are equal.</li>
<li><code>Equilateral</code>: A triangle where all sides are equal.</li>
</ul>
<pre><code class="lang-bash"><span class="hljs-built_in">read</span> a
<span class="hljs-built_in">read</span> b
<span class="hljs-built_in">read</span> c

<span class="hljs-keyword">if</span> [ <span class="hljs-variable">$a</span> == <span class="hljs-variable">$b</span> -a <span class="hljs-variable">$b</span> == <span class="hljs-variable">$c</span> -a <span class="hljs-variable">$a</span> == <span class="hljs-variable">$c</span> ]
<span class="hljs-keyword">then</span>
<span class="hljs-built_in">echo</span> EQUILATERAL

<span class="hljs-keyword">elif</span> [ <span class="hljs-variable">$a</span> == <span class="hljs-variable">$b</span> -o <span class="hljs-variable">$b</span> == <span class="hljs-variable">$c</span> -o <span class="hljs-variable">$a</span> == <span class="hljs-variable">$c</span> ]
<span class="hljs-keyword">then</span>
<span class="hljs-built_in">echo</span> ISOSCELES
<span class="hljs-keyword">else</span>
<span class="hljs-built_in">echo</span> SCALENE

<span class="hljs-keyword">fi</span>
</code></pre>
<p>In the example above, the script would ask the user to enter the three sides of the triangle. Next, it would compare the sides and decide the triangle type.</p>
<pre><code><span class="hljs-number">3</span>
<span class="hljs-number">4</span>
<span class="hljs-number">5</span>
SCALENE
</code></pre><h2 id="heading-conclusion">Conclusion</h2>
<p>You can easily branch your code based on conditions like <code>if..else</code> and make the code more dynamic. In this tutorial, you learned the syntax of <code>if...else</code> along with some examples.  </p>
<p>I hope you found this tutorial helpful.</p>
<p>What’s your favorite thing you learned from this tutorial? Let me know on <a target="_blank" href="https://twitter.com/hira_zaira">Twitter</a>!</p>
<p>You can read my other posts <a target="_blank" href="https://www.freecodecamp.org/news/author/zaira/">here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Rename a File in Linux – Bash Terminal Command ]]>
                </title>
                <description>
                    <![CDATA[ Renaming files is a very common operation whether you are using the command line or the GUI.  Compared to the GUI (or Graphical User Interface), the CLI is especially powerful. This is in part because you can rename files in bulk or even schedule the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/rename-file-linux-bash-command/</link>
                <guid isPermaLink="false">66adea6ffebac312b7307573</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zaira Hira ]]>
                </dc:creator>
                <pubDate>Fri, 30 Sep 2022 15:06:08 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/Copy-of-read-write-files-python--3-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Renaming files is a very common operation whether you are using the command line or the GUI. </p>
<p>Compared to the GUI (or Graphical User Interface), the CLI is especially powerful. This is in part because you can rename files in bulk or even schedule the scripts to rename files at a certain point in time.</p>
<p>In this tutorial, you will see how you can rename files in the Linux command line using the built-in <code>mv</code> command.</p>
<h2 id="heading-how-to-use-the-linux-mv-command">How to Use the Linux <code>mv</code> Command</h2>
<p>You can use the built-in Linux command <code>mv</code> to rename files. </p>
<p>The <code>mv</code> command follows this syntax:</p>
<pre><code class="lang-bash">mv [options] source_file destination_file
</code></pre>
<p>Here are some of the options that can come in handy with the <code>mv</code> command:</p>
<ul>
<li><code>-v</code> , <code>--verbose</code>: Explains what is being done.</li>
<li><code>-i</code>, <code>--interactive</code>: Prompts before renaming the file.</li>
</ul>
<p>Let's say you want to rename <code>index.html</code> to <code>web_page.html</code>. You use the <code>mv</code> command as follows:</p>
<pre><code class="lang-bash">zaira@Zaira:~/rename-files$ mv index.html web_page.html
</code></pre>
<p>Let's list the files and see if the file has been renamed:</p>
<pre><code class="lang-bash">zaira@Zaira:~/rename-files$ ls
web_page.html
</code></pre>
<h2 id="heading-how-to-name-files-in-bulk-using-mv">How to Name Files in Bulk Using <code>mv</code></h2>
<p>Let's discuss a script where you can rename files in a bulk using a loop and the <code>mv</code> command.</p>
<p>Here we have a list of files with the extension <code>.js</code>. </p>
<pre><code class="lang-bash">zaira@Zaira:~/rename-files$ ls -lrt
total 0
-rw-r--r-- 1 zaira zaira 0 Sep 30 00:24 index.js
-rw-r--r-- 1 zaira zaira 0 Sep 30 00:24 config.js
-rw-r--r-- 1 zaira zaira 0 Sep 30 00:24 blog.js
</code></pre>
<p>Next, you want to convert them to <code>.html</code>.</p>
<p>You can use the command below to rename all the files in the folder:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> *.js; <span class="hljs-keyword">do</span> mv -- <span class="hljs-string">"<span class="hljs-variable">$f</span>"</span> <span class="hljs-string">"<span class="hljs-variable">${f%.js}</span>.html"</span>; <span class="hljs-keyword">done</span>
</code></pre>
<p>Let's break down this long string to see what's happening under the hood:</p>
<ul>
<li>The first part [<code>for f in *.js</code>] tells the <code>for</code> loop to process each “.js” file in the directory.</li>
<li>The next part [<code>do mv -- "$f" "${f%.js}.html</code>] specifies what the processing will do. It is using <code>mv</code> to rename each file. The new file is going to be named with the original file’s name excluding the <code>.js</code> part. A new extension of <code>.html</code> will be appended instead.</li>
<li>The last part [<code>done</code>] simply ends the loop once all the files have been processed.</li>
</ul>
<pre><code class="lang-bash">zaira@Zaira:~/rename-files$ ls -lrt
total 0
-rw-r--r-- 1 zaira zaira 0 Sep 30 00:24 index.html
-rw-r--r-- 1 zaira zaira 0 Sep 30 00:24 config.html
-rw-r--r-- 1 zaira zaira 0 Sep 30 00:24 blog.html
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As you can see, renaming files is quite easy using the CLI. It can be really powerful when deployed in a script.</p>
<p>What’s your favorite thing you learned here? Let me know on <a target="_blank" href="https://twitter.com/hira_zaira">Twitter</a>!</p>
<p>You can read my other posts <a target="_blank" href="https://www.freecodecamp.org/news/author/zaira/">here</a>.</p>
<p><a target="_blank" href="https://www.freepik.com/free-vector/college-project-concept-illustration_29659818.htm">Image by storyset</a> on Freepik</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Bash Command Line Tips to Help You Work Faster ]]>
                </title>
                <description>
                    <![CDATA[ Learning the command line is essential for any aspiring developer. And to execute commands on the command line, you need a shell. The Bash shell is popular in Unix-like operating systems like Mac and Linux. In fact in most Linux distros, Bash is the ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bash-command-line-tips-to-help-you-work-faster/</link>
                <guid isPermaLink="false">66d4617055db48792eed3fb3</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Vinod Mathew Sebastian ]]>
                </dc:creator>
                <pubDate>Mon, 02 May 2022 19:56:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/Bash-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Learning the command line is essential for any aspiring developer.</p>
<p>And to execute commands on the command line, you need a shell.</p>
<p>The Bash shell is popular in Unix-like operating systems like Mac and Linux. In fact in most Linux distros, Bash is the default shell.</p>
<p>You can also use Bash in Windows via WSL (Windows Subsystem for Linux).</p>
<p>After learning some basic Bash commands, it's time to get up to speed.</p>
<p>This tutorial is not for absolute beginners, but I hope both novices and advanced users might get something out of it.</p>
<p>Here are the 10 Bash commands that'll help you work faster with your terminal.</p>
<h2 id="heading-1-use-control-l-to-clear-the-screen-and-control-d-to-exit">1. Use Control + L to clear the screen and Control + D to exit</h2>
<p>To clear the terminal screen, type <code>clear</code> on the command line.</p>
<p>To exit, type <code>exit</code>.</p>
<p>Better still, pressing Ctrl + l ( ⌘ + l ) clears the screen and Ctrl + d (⌘ + d) closes the terminal.</p>
<h2 id="heading-2-use-the-nohup-command-to-spawn-processes-that-dont-end-with-the-terminal-session">2. Use the <code>nohup</code> command to spawn processes that don't end with the terminal session</h2>
<p>Once programs are loaded into memory, they are called processes.</p>
<p>Sometimes, I open Firefox from the command line:<br><code>firefox https://freecodecamp.org</code>.</p>
<p>But as soon as I close the terminal, Firefox also crashes.</p>
<p>To prevent this, use the <code>nohup</code> (no hang up) command: <code>nohup firefox https://freecodecamp.org</code>.</p>
<p>Now when I close the terminal, Firefox doesn't crash but my tab crashes.</p>
<p>The fix: make Firefox a background process by appending the <code>&amp;</code> symbol.</p>
<p><code>nohup firefox https://freecodecamp.org &amp;</code></p>
<p>Now even if I quit the terminal, my tabs are all intact.</p>
<h2 id="heading-3-use-pkill-to-kill-processes-by-typing-in-only-a-part-of-the-name">3. Use <code>pkill</code> to kill processes by typing in only a part of the name</h2>
<p>By using the <code>killall</code> command, we can kill a process by its name:</p>
<p><code>killall firefox</code></p>
<p>Better still, use <code>pkill</code> to terminate by typing only a part of the name.</p>
<p><code>pkill fire*</code></p>
<h2 id="heading-4-prepend-the-time-command-to-know-how-fast-something-executes">4. Prepend the <code>time</code> command to know how fast something executes</h2>
<p>Do you want to know how long it takes something to execute in the shell?</p>
<p>Just prepend <code>time</code> to the command: <code>time gcc -g *.c</code>.</p>
<h2 id="heading-5-on-linux-use-cat-etcrel-to-view-the-distro-name">5. On Linux, use <code>cat /etc/*rel*</code> to view the distro name</h2>
<p>Typing <code>uname -a</code> shows the system information.</p>
<p>Wanna double check what distro you're running?</p>
<p>Just type <code>cat /etc/*rel*</code> on the shell and press enter.</p>
<h2 id="heading-6-use-the-sed-command-in-text-files-to-find-and-replace">6. Use the <code>sed</code> command in text files to find and replace</h2>
<p>Do you want to replace multiple occurrences of a word in a text file?</p>
<p>Use the <code>sed</code> command.</p>
<p><code>sed s'/apples/oranges/g' myfile.txt</code></p>
<p>Here, all the occurrences of the word 'apples' are changed into 'oranges'.</p>
<p>If you only need to replace the first occurrence in every line, just take out the 'g' suffix at the end: <code>sed s'/apples/oranges/' myfile.txt</code>.</p>
<p>The 'g' is for <em>global.</em></p>
<p>The forward slash <code>/</code> is the delimiter. In fact, you can use any delimiter.</p>
<p>Let's use a single underscore <code>_</code> as the delimiter: <code>sed s'_apples_oranges_'g</code> myfile.txt`.</p>
<p>Simply using <code>sed</code> only replaces on the standard output. The original file is unchanged.</p>
<p>To change the file 'in place', use the <code>-i</code> flag: <code>sed -i s'_apples_oranges_g' myfile.txt</code>.</p>
<h2 id="heading-7-know-the-public-ip-address-of-your-computer-using-curl">7. Know the public IP address of your computer using <code>curl</code></h2>
<p>There are two types of IP addresses: private and public.</p>
<p>A system assigns internal IP addresses which can be checked using the <code>ifconfig</code> command.</p>
<p>But do you want to know the public IP of your computer – the IP address that the ISP assigns to your interface?</p>
<p>While online, just use <code>curl ifconfig.me ; echo</code> or <code>curl ifconfig.co ; echo</code> on the command line.</p>
<h2 id="heading-8-use-ctrl-r-r-for-reverse-search">8. Use Ctrl + R (⌘ + R) for reverse search</h2>
<p>Pressing the 'up' arrow key shows the last command you've typed.</p>
<p>Typing <code>history</code> shows all the commands you have typed that are stored in bash history.</p>
<p>Better still, type Ctrl + r (⌘ + r) on the shell and start typing in the command.</p>
<p>As you type, the shell autocompletes from history. Press 'enter' as soon as you find the match.</p>
<p><strong>If you remember only one thing from this tutorial, remember this key combination: Ctrl + r (⌘ + r).</strong></p>
<p>It will save you a lot of time, guaranteed!</p>
<h2 id="heading-9-use-the-shell-for-doing-math">9. Use the shell for doing math</h2>
<p>For simple calculations that don't input or output fractions, you can simply use:</p>
<pre><code class="lang-typescript">:~$ echo $((<span class="hljs-number">19</span>*<span class="hljs-number">34</span>))
:~$ <span class="hljs-number">646</span>
</code></pre>
<p>For calculations that involve fractions, just <code>echo</code> the expression and pipe it into the <code>bc</code> command.</p>
<pre><code class="lang-typescript">:~$ echo <span class="hljs-string">"scale=2; 9*3/((2*2)+1)"</span> | bc
:~$ <span class="hljs-number">5.40</span>
</code></pre>
<p>Here, 'scale' is the precision we need. I have specified it to be two decimal points.</p>
<h2 id="heading-10-use-brace-expansion-to-create-files-in-bulk">10. Use brace expansion to create files in bulk</h2>
<p>How do we create 100 files inside a folder?</p>
<p><em>file1.txt, file2.txt, file3.txt ... file100.txt</em></p>
<p>By using brace expansion: <code>touch file{1..100}.txt</code>.</p>
<p>We need to create three files for our project: app.html, app.css, and app.js</p>
<p>Instead of creating one by one, we can simply use brace expansion to create all of them in one go.</p>
<pre><code class="lang-typescript">:~$ touch app.{html,css,js}
:~$ ls
app.html app.css app.js
:~$
</code></pre>
<p>Or inside the project folder, we need to create five directories: images, css, src, templates, and scripts.</p>
<p>We can use:</p>
<pre><code class="lang-typescript">:~$ mkdir {images,css,src,templates,scripts}
:~$ ls
images css src templates scripts
:~$
</code></pre>
<p>Only one caveat here: just ensure that there are no spaces between the words inside the braces.</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>I have listed 10 Bash command line tips by which you can work up to speed on the terminal.</p>
<p>Learn these Bash commands and it will hold you in good stead in your programming journey.</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ sudo apt-get update vs upgrade – What is the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ sudo apt-get update and sudo apt-get upgrade are two commands you can use to keep all of your packages up to date in Debian or a Debian-based Linux distribution. They're common commands for Linux admins and people doing DevOps, but are handy to know ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/sudo-apt-get-update-vs-upgrade-what-is-the-difference/</link>
                <guid isPermaLink="false">66ac883433a54a9b1a447936</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kristofer Koishigawa ]]>
                </dc:creator>
                <pubDate>Mon, 02 May 2022 19:30:12 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/gabriel-heinzer-4Mw7nkQDByk-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code> are two commands you can use to keep all of your packages up to date in Debian or a Debian-based Linux distribution.</p>
<p>They're common commands for Linux admins and people doing DevOps, but are handy to know even if you don't use the command line often.</p>
<p>In this article, I'll go into what both of these commands do, how to use them, and some frequently asked questions.</p>
<h2 id="heading-what-are-the-differences-between-sudo-apt-get-update-and-sudo-apt-get-upgrade">What Are the Differences Between <code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code>?</h2>
<p>The main difference is that <code>sudo apt-get update</code> fetches the latest version of the package list from your distro's software repository, and any third-party repositories you may have configured. In other words, it'll figure out what the latest version of each package and dependency is, but will not actually download or install any of those updates.</p>
<p>The <code>sudo apt-get upgrade</code> command downloads and installs the updates for each outdated package and dependency on your system. But just running <code>sudo apt-get upgrade</code> will not automatically upgrade the outdated packages – you'll still have a chance to review the changes and confirm that you want to perform the upgrades.</p>
<h2 id="heading-how-to-use-the-sudo-apt-get-update-command">How to Use the <code>sudo apt-get update</code> Command</h2>
<p>In your Debian-based Linux distro (Debian, Ubuntu, Linux Mint, Kali Linux, Raspberry Pi OS, and so on), open a terminal window.</p>
<p>Depending on your distro, the terminal might go by different names depending on how you open it. For example, in Ubuntu and Linux Mint, the default terminal is Gnome Terminal, but may be listed under Terminal in the application menu.</p>
<p>In the terminal, enter <code>sudo apt-get update</code> in the command line, enter in your admin password, and press the Enter key.</p>
<p>If there are updates, you'll see an output similar to this:</p>
<pre><code class="lang-bash">kris@pihole:~ $ sudo apt-get update
Hit:1 https://ftp.harukasan.org/raspbian/raspbian bullseye InRelease
Get:2 https://download.docker.com/linux/raspbian bullseye InRelease [26.7 kB]
Get:3 http://archive.raspberrypi.org/debian bullseye InRelease [23.7 kB]       
Get:4 http://packages.azlux.fr/debian buster InRelease [3,989 B]               
Get:5 http://archive.raspberrypi.org/debian bullseye/main armhf Packages [282 kB]
Get:6 http://packages.azlux.fr/debian buster/main armhf Packages [3,418 B]
Fetched 340 kB <span class="hljs-keyword">in</span> 4s (94.8 kB/s)     
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
3 packages can be upgraded. Run <span class="hljs-string">'apt list --upgradable'</span> to see them.
</code></pre>
<p>If you want to see which packages can be upgraded, run <code>apt list --upgradable</code>:</p>
<pre><code class="lang-bash">kris@pihole:~ $ apt list --upgradable
Listing... Done
libcamera0/stable 0~git20220426+18e68a9b-1 armhf [upgradable from: 0~git20220303+e68e0f1e-1]
raspi-config/stable 20220425 all [upgradable from: 20220419]
rpi-eeprom/stable 13.13-1 armhf [upgradable from: 13.12-1]
</code></pre>
<p>But if there are no newer versions of packages or dependencies in your distro's software repository, you'll see an output like this:</p>
<pre><code class="lang-bash">kris@pihole:~ $ sudo apt-get update
Get:1 https://download.docker.com/linux/raspbian bullseye InRelease [26.7 kB]
Hit:2 https://ftp.harukasan.org/raspbian/raspbian bullseye InRelease           
Hit:3 http://packages.azlux.fr/debian buster InRelease                         
Hit:4 http://archive.raspberrypi.org/debian bullseye InRelease
Fetched 26.7 kB <span class="hljs-keyword">in</span> 3s (8,789 B/s)
Reading package lists... Done
</code></pre>
<p>Notice that there is no mention of packages that can be upgraded, and no note about running <code>apt list --upgradable</code>.</p>
<p>But this does not necessarily mean there's no outdated software on your system, just that you already got the latest version of the package list. You may have run <code>sudo apt-get update</code> multiple times.</p>
<p>You can always run <code>apt list --upgradable</code> again to see if anything can be upgraded.</p>
<p>Or you can use the more modern <code>sudo apt update</code> command instead. This command will always show you the number of packages that can be upgraded, or a note saying everything is up to date.</p>
<p>For more information about the differences between <code>apt</code> and <code>apt-get</code>, <a class="post-section-overview" href="#what-s-the-difference-between-apt-get-and-apt">check out this section below</a>.</p>
<h2 id="heading-how-to-use-the-sudo-apt-get-upgrade-command">How to Use the <code>sudo apt-get upgrade</code> Command</h2>
<p>After running the <code>sudo apt-get update</code> command, in the same terminal window, type in <code>sudo apt-get upgrade</code>, enter your password if necessary, and hit enter.</p>
<p>Then, you'll see an output similar to this:</p>
<pre><code class="lang-bash">kris@pihole:~ $ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libcamera0 raspi-config rpi-eeprom
3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,616 kB of archives.
After this operation, 1,596 kB of additional disk space will be used.
Do you want to <span class="hljs-built_in">continue</span>? [Y/n]
</code></pre>
<p>Towards the bottom of the output, you'll see the packages that will be upgraded:</p>
<pre><code class="lang-bash">The following packages will be upgraded:
  libcamera0 raspi-config rpi-eeprom
3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
</code></pre>
<p>The amount of data that needs to be fetched, and the amount of storage space the upgraded packages will use once installed:</p>
<pre><code class="lang-bash">Need to get 2,616 kB of archives.
After this operation, 1,596 kB of additional disk space will be used.
</code></pre>
<p>And finally, you'll see a prompt asking if you want to continue with the upgrade:</p>
<pre><code class="lang-bash">Do you want to <span class="hljs-built_in">continue</span>? [Y/n]
</code></pre>
<p>You can enter <code>y</code>, <code>Y</code>, or <code>yes</code> to continue with the upgrade, or <code>n</code>, <code>N</code>, or <code>no</code> to exit out of the <code>upgrade</code> command.</p>
<p>If you choose to exit out, you'll see an output like this:</p>
<pre><code class="lang-bash">kris@pihole:~ $ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libcamera0 raspi-config rpi-eeprom
3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,616 kB of archives.
After this operation, 1,596 kB of additional disk space will be used.
Do you want to <span class="hljs-built_in">continue</span>? [Y/n] n
Abort.
</code></pre>
<p>If you choose to continue with the upgrade, you'll see a long output like this:</p>
<pre><code class="lang-bash">kris@pihole:~ $ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libcamera0 raspi-config rpi-eeprom
3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,616 kB of archives.
After this operation, 1,596 kB of additional disk space will be used.
Do you want to <span class="hljs-built_in">continue</span>? [Y/n] y
Get:1 http://archive.raspberrypi.org/debian bullseye/main armhf libcamera0 armhf 0~git20220426+18e68a9b-1 [548 kB]
Get:2 http://archive.raspberrypi.org/debian bullseye/main armhf raspi-config all 20220425 [30.3 kB]
Get:3 http://archive.raspberrypi.org/debian bullseye/main armhf rpi-eeprom armhf 13.13-1 [2,037 kB]
Fetched 2,616 kB <span class="hljs-keyword">in</span> 3s (1,019 kB/s)   
Reading changelogs... Done
(Reading database ... 43496 files and directories currently installed.)
Preparing to unpack .../libcamera0_0~git20220426+18e68a9b-1_armhf.deb ...
Unpacking libcamera0:armhf (0~git20220426+18e68a9b-1) over (0~git20220303+e68e0f1e-1) ...
Preparing to unpack .../raspi-config_20220425_all.deb ...
Unpacking raspi-config (20220425) over (20220419) ...
Preparing to unpack .../rpi-eeprom_13.13-1_armhf.deb ...
Unpacking rpi-eeprom (13.13-1) over (13.12-1) ...
Setting up rpi-eeprom (13.13-1) ...
Setting up libcamera0:armhf (0~git20220426+18e68a9b-1) ...
Setting up raspi-config (20220425) ...
Processing triggers <span class="hljs-keyword">for</span> man-db (2.9.4-2) ...
Processing triggers <span class="hljs-keyword">for</span> libc-bin (2.31-13+rpt2+rpi1+deb11u2) ...
</code></pre>
<p>And once that's complete, all of the outdated packages and dependencies will be updated.</p>
<p>One important thing to remember about the <code>sudo apt-get upgrade</code> command is that it only upgrades what it can without removing anything. </p>
<p>For example, if an upgrade requires a new dependency, the <code>upgrade</code> command will download and install it, but it will not remove the old dependency. Removing old dependencies requires a different command. You'll see this a lot when you upgrade to a new kernel version.</p>
<p>If you see a message similar to this after upgrading:</p>
<pre><code class="lang-bash">The following packages were automatically installed and are no longer required:
  g++-8 gir1.2-mutter-4 libapache2-mod-php7.2 libcrystalhd3
Use <span class="hljs-string">'sudo apt autoremove'</span> to remove them.
</code></pre>
<p>You can follow the suggestion and use <code>sudo apt autoremove</code> to remove those unnecessary packages.</p>
<h2 id="heading-how-to-use-special-options-with-the-sudo-apt-get-upgrade-command">How to Use Special Options With the <code>sudo apt-get upgrade</code> Command</h2>
<p>There are a number of special options or parameters that you can use with the <code>sudo apt-get upgrade</code> command, but two stand out: <code>--dry-run</code> and <code>--yes</code>.</p>
<h3 id="heading-how-to-use-the-dry-run-option">How to Use the <code>--dry-run</code> Option:</h3>
<p>The <code>--dry-run</code> (alternatively, <code>-s</code> or <code>--simulate</code>) option simulates what would happen during the upgrade process, but doesn't actually change anything on your system:</p>
<pre><code class="lang-bash">kris@pihole:~ $ sudo apt-get upgrade --dry-run
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libcamera0 raspi-config rpi-eeprom
3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Inst libcamera0 [0~git20220303+e68e0f1e-1] (0~git20220426+18e68a9b-1 Raspberry Pi Foundation:stable [armhf])
Inst raspi-config [20220331] (20220425 Raspberry Pi Foundation:stable [all])
Inst rpi-eeprom [13.12-1] (13.13-1 Raspberry Pi Foundation:stable [armhf])
Conf libcamera0 (0~git20220426+18e68a9b-1 Raspberry Pi Foundation:stable [armhf])
Conf raspi-config (20220425 Raspberry Pi Foundation:stable [all])
Conf rpi-eeprom (13.13-1 Raspberry Pi Foundation:stable [armhf])
</code></pre>
<p>Though again, while Debian and Debian-based distros are very stable, this option is useful if you want to make sure there are no conflicts during an upgrade.</p>
<h3 id="heading-how-to-use-the-yes-option">How to Use the <code>--yes</code> Option:</h3>
<p>The <code>--yes</code> (alternatively, <code>-y</code> or <code>--assume-yes</code>) option automatically answers yes to any prompts if it's safe to do so:</p>
<pre><code class="lang-bash">kris@pihole:~ $ sudo apt-get upgrade --yes
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libcamera0 raspi-config rpi-eeprom
3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,616 kB of archives.
After this operation, 1,596 kB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian bullseye/main armhf libcamera0 armhf 0~git20220426+18e68a9b-1 [548 kB]
Get:2 http://archive.raspberrypi.org/debian bullseye/main armhf raspi-config all 20220425 [30.3 kB]
Get:3 http://archive.raspberrypi.org/debian bullseye/main armhf rpi-eeprom armhf 13.13-1 [2,037 kB]
...
Processing triggers <span class="hljs-keyword">for</span> libc-bin (2.31-13+rpt2+rpi1+deb11u2) ...
</code></pre>
<p>Note that the <code>Do you want to continue? [Y/n]</code> is skipped above, and all packages are upgraded.</p>
<h2 id="heading-faqs">FAQs</h2>
<h3 id="heading-what-are-sudo-and-apt-get">What Are <code>sudo</code> and <code>apt-get</code>?</h3>
<p>An important thing to note about <code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code> is that both commands are made up of three parts: <code>sudo</code>, <code>apt-get</code>, and <code>update</code> or <code>upgrade</code>.</p>
<p><code>sudo</code> stands for "superuser do", and allows you to run programs with root or admin privileges.</p>
<p>For example, rebooting a system requires superuser/root-level privileges, so running <code>reboot</code> in the terminal might return errors similar to this:</p>
<pre><code>Failed to set wall message, <span class="hljs-attr">ignoring</span>: Interactive authentication required.
Failed to reboot system via logind: Interactive authentication required.
Failed to open initctl fifo: Permission denied
Failed to talk to init daemon.
</code></pre><p>But if you run <code>sudo reboot</code>, then enter your admin password, you will run the <code>reboot</code> command as a superuser, and your system will restart immediately.</p>
<p><code>apt-get</code> is a command line tool in Debian and Debian-based Linux distros that you use to install and manage packages.</p>
<h3 id="heading-whats-the-difference-between-apt-get-and-apt">What's the Difference Between <code>apt-get</code> and <code>apt</code>?</h3>
<p><code>apt</code> is a more modern tool for installing and managing applications on Debian and Debian-based distros.</p>
<p>For the most part, <code>apt</code> and <code>apt-get</code> can be used interchangeably – <code>sudo apt update</code> and <code>sudo apt-get update</code> both update the package list on your system. </p>
<p>The main differences you'll notice is that <code>apt</code> is easier to type, its output is generally more useful, and it includes some user-friendly features like a progress bar when installing packages.</p>
<p>While most of the examples in this article use <code>apt-get</code>, I strongly encourage you to use <code>apt</code> instead.</p>
<h3 id="heading-are-sudo-apt-get-update-and-sudo-apt-get-upgrade-safe-to-use">Are <code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code> Safe to Use?</h3>
<p>Yes, Debian and Debian-based distros are generally very stable, and the <code>update</code> and <code>upgrade</code> commands are safe to use. This is because major updates for packages / dependencies, and the distros themselves, are only released once or twice a year.</p>
<p>The downside is that, unlike with bleeding edge distros like Arch Linux, if you want to use the most recent version of a package, you might need to put in some extra work. You may need to configure a third-party repository via a PPA, use an alternative packaging system like Snap of Flatpak, or compile the package yourself.</p>
<p>But the stability that comes with slightly older software is worth it, at least in my opinion.</p>
<h3 id="heading-can-you-chain-the-sudo-apt-get-update-and-sudo-apt-get-upgrade-commands">Can You Chain the <code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code> Commands?</h3>
<p>You might be thinking, isn't it tedious to run <code>sudo apt-get update</code>, wait for that to complete, then run <code>sudo apt-get upgrade</code>?</p>
<p>While both <code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code> run pretty quickly, sometimes it's easier to execute a string of commands and check back on them a few minutes later.</p>
<p>With the <code>&amp;&amp;</code> operator, you can chain multiple commands together like this:</p>
<pre><code class="lang-bash">sudo apt-get update &amp;&amp; sudo apt-get upgrade
</code></pre>
<p>The important thing to remember with the <code>&amp;&amp;</code> operator is that the command after the operator only runs if the command before it is successful.</p>
<p>Using the example above, <code>sudo apt-get upgrade</code> only runs if <code>sudo apt-get update</code> succeeds. If there's some sort of error, like a network problem while updating the package list, then <code>sudo apt-get update</code> is skipped.</p>
<h3 id="heading-what-are-sudo-apt-get-dist-upgrade-and-sudo-apt-full-upgrade-and-are-they-safe-to-use">What Are <code>sudo apt-get dist-upgrade</code> and <code>sudo apt full-upgrade</code>, and Are They Safe to Use?</h3>
<p>According to <a target="_blank" href="https://askubuntu.com/questions/770135/apt-full-upgrade-versus-apt-get-dist-upgrade">this Stack Overflow thread</a>, these commands do the same thing under the hood – they upgrade outdated packages, and also intelligently remove some packages whenever necessary.</p>
<p>Essentially they're like the combination of the <code>sudo apt-get upgrade</code> and <code>sudo apt autoremove</code> commands.</p>
<p>Running these commands <em>should</em> be safe in most cases.</p>
<p>But a lot of people, myself included, recommend using <code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code> instead. You have more of a chance to review upcoming changes, and since <code>upgrade</code> never removes packages, it's less destructive.</p>
<h2 id="heading-thanksforreadingsh"><code>./thanks_for_reading.sh</code></h2>
<p>If you found this breakdown on <code>sudo apt-get update</code> and <code>sudo apt-get upgrade</code> useful, please share it with your friends so more people can benefit from it.</p>
<p>Also, feel free to reach out on <a target="_blank" href="https://twitter.com/kriskoishigawa">Twitter</a> and let me know what you think.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Command Line for Beginners – How to Use the Terminal Like a Pro [Full Handbook] ]]>
                </title>
                <description>
                    <![CDATA[ Hi everyone! In this article we'll take a good look at the command line (also known as the CLI, console, terminal or shell). The command line is one of the most useful and efficient tools we have as developers and as computer users in general. But us... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/command-line-for-beginners/</link>
                <guid isPermaLink="false">66d45ef6264384a65d5a9520</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ German Cocca ]]>
                </dc:creator>
                <pubDate>Tue, 05 Apr 2022 16:45:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/pexels-pixabay-207580.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hi everyone! In this article we'll take a good look at the command line (also known as the CLI, console, terminal or shell).</p>
<p>The command line is one of the most useful and efficient tools we have as developers and as computer users in general. But using it can feel a bit overwhelming and complex when you're starting out.</p>
<p>In this article I'll try my best to simply explain the parts that make up the command line interface, and the basics of how it works, so you can start using it for your daily tasks.</p>
<p>Let's go! =D</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-difference-between-console-command-line-cli-terminal-and-shell">Difference between console, terminal, command line (CLI) and Shell</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-console">Console</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-terminal">Terminal</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shell">Shell</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-command-line-or-cli-command-line-interface">Command line (CLI)</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-why-should-i-even-care-about-using-the-terminal">Why should I even care about using the terminal?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-different-kinds-of-shells">Different kinds of shells</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-a-bit-of-history-posix">A bit of history - Posix</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-do-i-know-what-shell-im-running">How do I know what shell I'm running?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-shell-is-better">What shell is better?</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-a-comment-about-customization">A comment about customization</a></li>
</ul>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-most-common-and-useful-commands-to-use">Most common and useful commands to use</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-git-commands">Git commands</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-our-first-script">Our first script</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-round-up">Round up</a></p>
</li>
</ul>
<h1 id="heading-difference-between-console-command-line-cli-terminal-and-shell">Difference between console, command line (CLI), terminal and Shell</h1>
<p>I think a good place to start is to know exactly what the command line is.</p>
<p>When referring to this, you may have heard the terms Terminal, console, command line, CLI, and shell. People often use these words interchangeably but the truth is they're actually different things.</p>
<p>Differentiating each isn't necesarilly crucial knwoledge to have, but it will help clarify things. So lets briefly explain each one.</p>
<h2 id="heading-console">Console:</h2>
<p>The console is the <strong>physical device</strong> that allows you to interact with the computer.</p>
<p>In plain English, it's your computer screen, keyboard, and mouse. As a user, you interact with your computer <strong>through</strong> your console.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image_13b2c80d-a2d6-4429-8ca6-f053340897cc.png" alt="image_13b2c80d-a2d6-4429-8ca6-f053340897cc" width="600" height="400" loading="lazy"></p>
<h2 id="heading-terminal">Terminal:</h2>
<p>A terminal is a text input and output environment. It is a <strong>program</strong> that acts as a <strong>wrapper</strong> and allows us to enter commands that the computer processes.</p>
<p>In plain English again, it's the "window" in which you enter the actual commands your computer will process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/terminal.png" alt="terminal" width="600" height="400" loading="lazy"></p>
<p>Keep in mind the terminal is a program, just like any other. And like any program, you can install it and uninstall it as you please. It's also possible to have many terminals installed in your computer and run whichever you want whenever you want.</p>
<p>All operating systems come with a default terminal installed, but there are many options out there to choose from, each with its own functionalities and features.</p>
<h2 id="heading-shell">Shell:</h2>
<p>A shell is a <strong>program</strong> that acts as command-line interpreter. It <strong>processes commands</strong> and <strong>outputs the results</strong>. It interprets and processes the commands entered by the user.</p>
<p>Same as the terminal, the shell is a program that comes by default in all operating systems, but can also be installed and uninstalled by the user.</p>
<p>Different shells come with different syntax and characteristics as well. It's also possible to have many shells installed at your computer and run each one whenever you want.</p>
<p>In most Linux and Mac operating systems the default shell is Bash. While on Windows it's Powershell. Some other common examples of shells are Zsh and Fish.</p>
<p>Shells work also as <strong>programming languages</strong>, in the sense that with them we can build <strong>scripts</strong> to make our computer execute a certain task. Scripts are nothing more than a series of instructions (commands) that we can save on a file and later on execute whenever we want.</p>
<p>We'll take a look at scripts later on in this article. For now just keep in mind that the shell is the program your computer uses to "understand" and execute your commands, and that you can also use it to program tasks.</p>
<p>Also keep in mind that the terminal is the program in which the shell will run. But both programs are independent. That means, I can have any shell run on any terminal. There's no dependance between both programs in that sense.</p>
<h2 id="heading-command-line-or-cli-command-line-interface">Command line or CLI (command line interface):</h2>
<p>The CLI is the interface in which we enter commands for the computer to process. In plain English once again, it's the space in which you enter the commands the computer will process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/cli.png" alt="cli" width="600" height="400" loading="lazy"></p>
<p>This is practically the same as the terminal and in my opinion these terms can be used interchangeably.</p>
<p>One interesting thing to mention here is that most operating systems have two different types of interfaces:</p>
<ul>
<li><p>The <strong>CLI</strong>, which takes commands as inputs in order for the computer to execute tasks.</p>
</li>
<li><p>The other is the <strong>GUI</strong> (graphical user interface), in which the user can see things on the screen and click on them and the computer will respond to those events by executing the corresponding task.</p>
</li>
</ul>
<h1 id="heading-why-should-i-even-care-about-using-the-terminal">Why should I even care about using the terminal?</h1>
<p>We just mentioned that most operating systems come with a GUI. So if we can see things on the screen and click around to do whatever we want, you might wonder why you should learn this complicated terminal/cli/shell thing?</p>
<p>The first reason is that for many tasks, it's just <strong>more efficient</strong>. We'll see some examples in a second, but there are many tasks where a GUI would require many clicks around different windows. But on the CLI these tasks can be executed with a single command.</p>
<p>In this sense, being comfortable with the command line will help you save time and be able to execute your tasks quicker.</p>
<p>The second reason is that by using commands you can easily <strong>automate tasks</strong>. As previously mentioned, we can build scripts with our shell and later on execute those scripts whenever we want. This is incredibly useful when dealing with repetitive tasks that we don't want to do over and over again.</p>
<p>Just to give some examples, we could build a script that creates a new online repo for us, or that creates a certain infrastructure on a cloud provider for us, or that executes a simpler task like changing our screen wallpaper every hour.</p>
<p>Scripting is a great way to save up time with repetitive tasks.</p>
<p>The third reason is that sometimes the CLI will be the <strong>only way</strong> in which we'll be able to interact with a computer. Take, for example, the case when you would need to interact with a cloud platform server. In most of these cases, you won't have a GUI available, just a CLI to run commands in.</p>
<p>So being comfortable with the CLI will allow you to interact with computers on all ocassions.</p>
<p>The last reason is it looks cool and it's fun. You don't see movie hackers clicking around their computers, right? ;)</p>
<h1 id="heading-different-kinds-of-shells">Different kinds of shells</h1>
<p>Before diving into the actual commands you can run in your terminal, I think it's important to recognize the different types of shells out there and how to identify which shell you're currently running.</p>
<p>Different shells come with different syntax and different features, so to know exactly what command to enter, you first need to know what shell you're running.</p>
<h2 id="heading-a-bit-of-history-posix">A bit of history – Posix</h2>
<p>For shells, there's a common standard called <a target="_blank" href="https://en.wikipedia.org/wiki/POSIX"><strong>Posix</strong></a>.</p>
<p>Posix works for shells in a very similar way that ECMAScript works for JavaScript. It's a standard that dictates certain characteristics and features that all shells should comply with.</p>
<p>This standard was stablished in the 1980's and most current shells were developed according to that standard. That's why most shells share similar syntax and similar features.</p>
<h2 id="heading-how-do-i-know-what-shell-im-running">How do I know what shell I'm running?</h2>
<p>To know what shell you're currently running, just open your terminal and enter <code>echo $0</code>. This will print the current running program name, which in this case is the actual shell.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/screenshot-1.png" alt="screenshot-1" width="600" height="400" loading="lazy"></p>
<h2 id="heading-what-shell-is-better">What shell is better?</h2>
<p>There's not A LOT of difference between most shells. Since most of them comply with the same standard, you'll find that most of them work similarly.</p>
<p>There are some slight differences you might want to know, though:</p>
<ul>
<li><p>As mentioned, <strong>Bash</strong> is the most widely used and comes installed by default on Mac and Linux.</p>
</li>
<li><p><strong>Zsh</strong> is very similar to Bash, but it was created after it and comes with some nice improvements over it. If you'd like to have more detail about its differences, <a target="_blank" href="https://linuxhint.com/differences_between_bash_zsh/#:~:text=It%20has%20many%20features%20like,by%20default%20with%20Linux%20distribution.">here's a cool article</a> about it.</p>
</li>
<li><p><strong>Fish</strong> is another commonly used shell that comes with some nice built-in features and configurations such as autocompletion and syntax highlighting. The thing about Fish is that it's not Posix complaint, while Bash and Zsh are. This means that some of the commands you'll be able to run on Bash and Zsh won't run on Fish and viceversa. This makes Fish scripting less compatible with most computers compared to Bash and Zsh.</p>
</li>
<li><p>There are also other shells like <strong>Ash</strong> or <strong>Dash</strong> (the naming just makes everything more confusing, I know...) that are stripped-down versions of Posix shells. This means they only offer the features required in Posix, and nothing else. While Bash and Zsh <strong>add more features</strong> than what Posix requires.</p>
</li>
</ul>
<p>The fact that shells add more features makes them easier and friendlier to interact with, but slower to execute scripts and commands.</p>
<p>So a common practice is to use this "enhanced" shells like Bash or Zsh for general interaction, and a "stripped" shell like Ash or Dash to execute scripts.</p>
<p>When we get to scripting later on, we'll see how we can define what shell will execute a given script.</p>
<p>If you're interested in a more detailed comparison between these shells, <a target="_blank" href="https://www.youtube.com/watch?v=dRdGq8khTJc">here's a video that explains it really well</a>:</p>
<p>If had to recommend a shell, I would recommend bash as it's the most standard and commonly-used one. This means you'll be able to translate your knowledge into most environments.</p>
<p>But again, truth is there's not A LOT of difference between most shells. So in any case you can try a few and see which one you like best. ;)</p>
<h3 id="heading-a-comment-about-customization">A comment about customization</h3>
<p>I just mentioned that Fish comes with built-in configuration such as autocompletion and syntax highlighting. This come built-in in Fish, but in Bash or Zsh you can configure these features, too.</p>
<p>The point is that shells are customizable. You can edit how the program works, what commands you have available, what information your prompt shows, and more.</p>
<p>We won't see customization options in detail here, but know that when you install a shell in your computer, certain files will be created on your system. Later on you can edit those files to customize your program.</p>
<p>Also, there are many plugins available online that allow you to customize your shell in an easier way. You just install them and get the features that plugin offers. Some examples are <a target="_blank" href="https://ohmyz.sh/">OhMyZsh</a> and <a target="_blank" href="https://starship.rs/">Starship</a>.</p>
<p>These customization options are also true for Terminals.</p>
<p>So not only do you have many shell and terminal options to choose from – you also have many configuration options for each shell and terminal.</p>
<p>If you're starting out, all this information can feel a bit overwhelming. But just know that there are many options available, and each option can be customized too. That's it.</p>
<h1 id="heading-most-common-and-useful-commands-to-use">Most common and useful commands to use</h1>
<p>Now that we have a foundation of how the CLI works, let's dive into the most useful commands you can start to use for your daily tasks.</p>
<p>Keep in mind that these examples will be based on my current configuration (Bash on a Linux OS). But most commands should apply to most configurations anyway.</p>
<ul>
<li><strong>Echo</strong> prints in the terminal whatever parameter we pass it.</li>
</ul>
<pre><code class="lang-plaintext">echo Hello freeCodeCamp! // Output: Hello freeCodeCamp!
</code></pre>
<ul>
<li><strong>pwd</strong> stands for print working directory and it prints the "place" or directory we are currently at in the computer.</li>
</ul>
<pre><code class="lang-plaintext">pwd // Output: /home/German
</code></pre>
<ul>
<li><strong>ls</strong> presents you the contents of the directory you're currently in. It will present you with both the files and other directories your current directory contains.</li>
</ul>
<p>For example, here I'm on a React project directory I've been working on lately:</p>
<pre><code class="lang-plaintext">ls // Output:
node_modules  package.json  package-lock.json  public  README.md  src
</code></pre>
<p>If you pass this command the flag or paremter <code>-a</code> It will also show you hidden files or directories. Like <code>.git</code> or <code>.gitignore</code> files</p>
<pre><code class="lang-plaintext">ls -a // Output:
.   .env  .gitignore    package.json       public     src
..  .git  node_modules  package-lock.json  README.md
</code></pre>
<ul>
<li><strong>cd</strong> is short for Change directory and it will take you from your current directory to another.</li>
</ul>
<p>While on my home directory, I can enter <code>cd Desktop</code> and it will take me to the Desktop Directory.</p>
<p>If I want to go up one directory, meaning go to the directory that contains the current directory, I can enter <code>cd ..</code></p>
<p>If you enter <code>cd</code> alone, it will take you straight to your home directory.</p>
<ul>
<li><strong>mkdir</strong> stands for make directory and it will create a new directory for you. You have to pass the command the directory name parameter.</li>
</ul>
<p>If I wanted to create a new directory called "Test" I would enter <code>mkdir test</code>.</p>
<ul>
<li><p><strong>rmdir</strong> stands for Remove directory and it does just that. It needs the directory name parameter just as <code>mkdir</code>: <code>rmdir test</code>.</p>
</li>
<li><p><strong>touch</strong> allows you to create an empty file in your current directory. As parameters it takes the file name, like <code>touch test.txt</code>.</p>
</li>
<li><p><strong>rm</strong> allows you to delete files, in the same way <code>rmdir</code> allows you to remove directories. <code>rm test.txt</code></p>
</li>
<li><p><strong>cp</strong> allows you to copy files or directories. This command takes two parameters: the first one is the file or directory you want to copy, and the second one is the destination of your copy (where do you want to copy your file/directory to).</p>
</li>
</ul>
<p>If I want to make a copy of my txt file in the same directory, I can enter the following:</p>
<pre><code class="lang-plaintext">cp test.txt testCopy.txt
</code></pre>
<p>See that the directory doesn't change, as for "destination" I enter the new name of the file.</p>
<p>If I wanted to copy the file into a diferent directory, but keep the same file name, I can enter this:</p>
<pre><code class="lang-plaintext">cp test.txt ./testFolder/
</code></pre>
<p>And if I wanted to copy to a different folder changing the field name, of course I can enter this:</p>
<pre><code class="lang-plaintext">cp test.txt ./testFolder/testCopy.txt
</code></pre>
<ul>
<li><strong>mv</strong> is short for move, and lets us move a file or directory from one place to another. That is, create it in a new directory and delete it in the previous one (same as you could do by cutting and pasting).</li>
</ul>
<p>Again, this command takes two paremers, the file or directory we want to move and the destination.</p>
<pre><code class="lang-plaintext">mv test.txt ./testFolder/
</code></pre>
<p>We can change the name of the file too in the same command if we want to:</p>
<pre><code class="lang-plaintext">mv test.txt ./testFolder/testCopy.txt
</code></pre>
<ul>
<li><strong>head</strong> allows you to view the beginning of a file or piped data directly from the terminal.</li>
</ul>
<pre><code class="lang-plaintext">head test.txt // Output:
this is the beginning of my test file
</code></pre>
<ul>
<li><strong>tail</strong> works the same but it will show you the end of the file.</li>
</ul>
<pre><code class="lang-plaintext">tail test.txt // Output:

this is the end of my test file
</code></pre>
<ul>
<li>The <strong>--help</strong> flag can be used on most commands and it will return info on how to use that given command.</li>
</ul>
<pre><code class="lang-plaintext">cd --help // output:
cd: cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
</code></pre>
<p>Change the current directory to DIR. The default DIR is the value of the HOME shell variable.</p>
<p>The variable CDPATH defines the search path for the directory containing DIR. Alternative directory names in CDPATH are separated by a colon <code>:</code>.</p>
<p>A null directory name is the same as the current directory if DIR begins with <code>...</code>.</p>
<ul>
<li>In a similar way, the <strong>man</strong> command will return info about any particular command.</li>
</ul>
<pre><code class="lang-plaintext">    man cp // output:

    CP(1)                            User Commands                           CP(1)

    NAME
           cp - copy files and directories

    SYNOPSIS
           cp [OPTION]... [-T] SOURCE DEST
           cp [OPTION]... SOURCE... DIRECTORY
           cp [OPTION]... -t DIRECTORY SOURCE...

    DESCRIPTION
           Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

           Mandatory  arguments  to  long  options are mandatory for short options
           too.

           -a, --archive
                  same as -dR --preserve=all

           --attributes-only
                  don't copy the file data, just the attributes
    ...
</code></pre>
<p>You can even enter <code>man bash</code> and that will return a huge manual about everything there's to know about this shell. ;)</p>
<ul>
<li><strong>code</strong> will open your default code editor. If you enter the command alone, it just opens the editor with the latest file/directory you opened.</li>
</ul>
<p>You can also open a given file by passing it as parameter: <code>code test.txt</code>.</p>
<p>Or open a new file by passing the new file name: <code>code thisIsAJsFile.js</code>.</p>
<ul>
<li><strong>edit</strong> will open text files on your default command line text editor (which if you're on Mac or Linux will likely be either Nano or Vim).</li>
</ul>
<p>If you open your file and then can't exit your editor, first look at this meme:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/vimExit.png" alt="vimExit" width="600" height="400" loading="lazy"></p>
<p>And then type <code>:q!</code> and hit enter.</p>
<p>The meme is funny because everyone struggles with CLI text editors at first, as most actions (like exiting the editor) are done with keyboard shortcuts. Using these editors is a whole other topic, so go look for tutorials if you're interested in learning more. ;)</p>
<ul>
<li><p><strong>ctrl+c</strong> allows you to exit the current process the terminal is running. For example, if you're creating a react app with <code>npx create-react-app</code> and want to cancel the build at some point, just hit <strong>ctrl+c</strong> and it will stop.</p>
</li>
<li><p>Copying text from the terminal can be done with <strong>ctrl+shift+c</strong> and pasting can be done with <strong>ctrl+shift+v</strong></p>
</li>
<li><p><strong>clear</strong> will clear your terminal from all previous content.</p>
</li>
<li><p><strong>exit</strong> will close your terminal and (this is not a command but it's cool too) <strong>ctrl+alt+t</strong> will open a new terminal for you.</p>
</li>
<li><p>By pressing <strong>up and down keys</strong> you can navigate through the previous commands you entered.</p>
</li>
<li><p>By hitting <strong>tab</strong> you will get autocompletion based on the text you've written so far. By hitting <strong>tab twice</strong> you'll get suggestions based on the text you've written so far.</p>
</li>
</ul>
<p>For example if I write <code>edit test</code> and <strong>tab twice</strong>, I get <code>testFolder/ test.txt</code>. If I write <code>edit test.</code> and hit <strong>tab</strong> my text autocompletes to <code>edit test.txt</code></p>
<h2 id="heading-git-commands">Git commands</h2>
<p>Besides working around the file system and installing/uninstalling things, interacting with Git and online repos is probably the most common things you're going to use the terminal for as a developer.</p>
<p>It's a whole lot more efficient to do it from the terminal than by clicking around, so let's take a look at the most useful git commands out there.</p>
<ul>
<li><strong>git init</strong> will create a new local repository for you.</li>
</ul>
<pre><code class="lang-plaintext">git init // output:
Initialized empty Git repository in /home/German/Desktop/testFolder/.git/
</code></pre>
<ul>
<li><p><strong>git add</strong> adds one or more files to staging. You can either detail a specific file to add to staging or add all changed files by typing <code>git add .</code></p>
</li>
<li><p><strong>git commit</strong> commits your changes to the repository. Commits must always be must be accompanied by the <code>-m</code> flag and commit message.</p>
</li>
</ul>
<pre><code class="lang-plaintext">git commit -m 'This is a test commit' // output:
[master (root-commit) 6101dfe] This is a test commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test.js
</code></pre>
<ul>
<li><strong>git status</strong> tells you what branch are you currently on and whether you have changes to commit or not.</li>
</ul>
<pre><code class="lang-plaintext">git status  // output:
On branch master
nothing to commit, working tree clean
</code></pre>
<ul>
<li><strong>git clone</strong> allows you to clone (copy) a repository into the directory you're currently in. Keep in mind you can clone both remote repositories (in GitHub, GitLab, and so on) and local repositories (those that are stored in your computer).</li>
</ul>
<pre><code class="lang-plaintext">git clone https://github.com/coccagerman/MazeGenerator.git // output:
Cloning into 'MazeGenerator'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 15 (delta 1), reused 11 (delta 0), pack-reused 0
Unpacking objects: 100% (15/15), done.
</code></pre>
<ul>
<li><strong>git remote add origin</strong> is used to detail the URL of the remote repository you're going to use for your project. In case you'd like to change it at some point, you can do it by using the command <code>git remote set-url origin</code>.</li>
</ul>
<pre><code class="lang-plaintext">git remote add origin https://github.com/coccagerman/testRepo.git
</code></pre>
<blockquote>
<p>Keep in mind you need to create your remote repo first in order to get its URL. We'll see how you can do this from the command line with a little script later on. ;)</p>
</blockquote>
<ul>
<li><strong>git remote -v</strong> lets you list the current remote repository you're using.</li>
</ul>
<pre><code class="lang-plaintext">git remote -v // output:
origin    https://github.com/coccagerman/testRepo.git (fetch)
origin    https://github.com/coccagerman/testRepo.git (push)
</code></pre>
<ul>
<li><strong>git push</strong> uploads your commited changes to your remote repo.</li>
</ul>
<pre><code class="lang-plaintext">git push // output:
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 266 bytes | 266.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
</code></pre>
<ul>
<li><strong>git branch</strong> lists all the available branches on your repo and tells you what branch you're currently on. If you want to create a new branch, you just have to add the new branch name as parameter like <code>git branch &lt;branch name&gt;</code>.</li>
</ul>
<pre><code class="lang-plaintext">git branch // output:
* main
</code></pre>
<ul>
<li><strong>git checkout</strong> moves you from one branch to another. It takes your destination branch as paremeter.</li>
</ul>
<pre><code class="lang-plaintext">git checkout newBranch // output:
Switched to branch 'newBranch'
</code></pre>
<ul>
<li><strong>git pull</strong> pulls (downloads) the code from your remote repository and combines it with your local repo. This is particularly useful when working in teams, when many developers are working on the same code base. In this case each developer periodically pulls from the remote repo in order to work in a code base that includes the changes done by all the other devs.</li>
</ul>
<p>If there's new code in your remote repo, the command will return the actual files that were modified in the pull. If not, we get <code>Already up to date</code>.</p>
<pre><code class="lang-plaintext">git pull // output:
Already up to date.
</code></pre>
<ul>
<li><strong>git diff</strong> allows you to view the differences between the branch you're currently in and another.</li>
</ul>
<pre><code class="lang-plaintext">git diff newBranch // output:
diff --git a/newFileInNewBranch.js b/newFileInNewBranch.js
deleted file mode 100644
index e69de29..0000000
</code></pre>
<p>As a side comment, when comparing differences between branches or repos, ussually visual tools like <a target="_blank" href="https://meldmerge.org/">Meld</a> are used. It's not that you can't visualize it directly in the terminal, but this tools are greate for a clearer visualization.</p>
<ul>
<li><strong>git merge</strong> merges (combines) the branch you're currently in with another. Keep in mind the changes will be incorporated only to the branch you're currently in, not to the other one.</li>
</ul>
<pre><code class="lang-plaintext">git merge newBranch // output:
Updating f15cf51..3a3d62f
Fast-forward
 newFileInNewBranch.js | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 newFileInNewBranch.js
</code></pre>
<ul>
<li><strong>git log</strong> lists all previous commits you've done in the repo.</li>
</ul>
<pre><code class="lang-plaintext">git log // output:
commit 3a3d62fe7cea7c09403c048e971a5172459d0948 (HEAD -&gt; main, tag: TestTag, origin/main, newBranch)
Author: German Cocca &lt;german.cocca@avature.net&gt;
Date:   Fri Apr 1 18:48:20 2022 -0300

    Added new file

commit f15cf515dd3ec398210108dce092debf26ff9e12
Author: German Cocca &lt;german.cocca@avature.net&gt;
    ...
</code></pre>
<ul>
<li>The <strong>--help</strong> flag will show you information about a given command, exactly the same way it works with bash.</li>
</ul>
<pre><code class="lang-plaintext">git diff --help // output:
GIT-DIFF(1)                       Git Manual                       GIT-DIFF(1)

NAME
       git-diff - Show changes between commits, commit and working tree, etc

SYNOPSIS
       git diff [options] [&lt;commit&gt;] [--] [&lt;path&gt;...]
       git diff [options] --cached [&lt;commit&gt;] [--] [&lt;path&gt;...]
       ...
</code></pre>
<h1 id="heading-our-first-script">Our first script</h1>
<p>Now we're ready to get to the truly fun and awesome part of the command line, scripting!</p>
<p>As I mentioned previously, a script is nothing more than a series of commands or instructions that we can execute at any given time. To explain how we can code one, we'll use a simple example that will allow us to create a github repo by running a single command. ;)</p>
<ul>
<li><p>First thing to do is create a <code>.sh</code> file. You can put it wherever want. I called mine <code>newGhRepo.sh</code>.</p>
</li>
<li><p>Then open it on your text/code editor of choice.</p>
</li>
<li><p>On our first line, we'll write the following: <code>#! /bin/sh</code></p>
</li>
</ul>
<p>This is called a <strong>shebang</strong>, and its function is to declare what shell is going to run this script.</p>
<p>Remember previously when we mentioned that we can use a given shell for general interaction and another given shell for executing a script? Well, the shebang is the instruction that dictates what shell runs the script.</p>
<p>As mentioned too, we're using a "stripped down" shell (also known as sh shells) to run the scripts as they're more efficient (though the difference might be unnoticeable to be honest, It's just a personal preference). In my computer I have dash as my sh shell.</p>
<p>If we wanted this script to run with bash the shebang would be <code>#! /bin/bash</code></p>
<ul>
<li>Our next line will be <code>repoName=$1</code></li>
</ul>
<p>Here we're declaring a <strong>variable</strong> called repoName, and assigning it to the value of the first parameter the script receives.</p>
<p>A <strong>parameter</strong> is a set of characters that is entered after the script/comand. Like with the <code>cd</code> command, we need to specify a directory parameter in order to change directory (ie: <code>cd testFolder</code>).</p>
<p>A way we can identify parameters within a script is by using dollar sign and the order in which that parameter is expected.</p>
<p>If I'm expecting more than one parameter I could write:</p>
<pre><code class="lang-plaintext">paramOne=$1
paramTwo=$2
paramThree=$3
...
</code></pre>
<ul>
<li>So we're expecting the repository name as parameter of our script. But what happens if the user forgets to enter it? We need to plan for that so next we're going to code a <strong>conditional</strong> that keeps asking the user to enter the repo name until that parameter is received.</li>
</ul>
<p>We can do that like this:</p>
<pre><code class="lang-plaintext">while [ -z "$repoName" ]
do
   echo 'Provide a repository name'
   read -r -p $'Repository name:' repoName
done
</code></pre>
<p>What we're doing here is:</p>
<ol>
<li><p>While the repoName variable is not assigned (<code>while [ -z "$repoName" ]</code>)</p>
</li>
<li><p>Write to the console this message (<code>echo 'Provide a repository name'</code>)</p>
</li>
<li><p>Then read whatever input the user provides and assign the input to the repoName variable (<code>read -r -p $'Repository name:' repoName</code>)</p>
</li>
</ol>
<ul>
<li>Now that we have our repo name in place, we can create our local Git repo like this:</li>
</ul>
<pre><code class="lang-plaintext">echo "# $repoName" &gt;&gt; README.md
git init
git add .
git commit -m "First commit"
</code></pre>
<p>This is creating a readme file and writting a single line with the repo name (<code>echo "# $repoName" &gt;&gt; README.md</code>) and then initializing the git repo and making a first commit.</p>
<ul>
<li>Then it's time to upload our repo to github. To do that we're going to take advantage of the <a target="_blank" href="https://docs.github.com/en/rest/reference/repos">github API</a> in the following command:</li>
</ul>
<p><code>curl -u coccagerman https://api.github.com/user/repos -d '{"name": "'"$repoName"'", "private":false}'</code></p>
<p><strong>curl</strong> is a command to transfer data from or to a server, using one of the many supported protocols.</p>
<p>Next we're using the <code>-u</code> flag to declare the user we're creating the repo for (<code>-u coccagerman</code>).</p>
<p>Next comes the endpoint provided by the GitHub API (<code>https://api.github.com/user/repos</code>)</p>
<p>And last we're using the <code>-d</code> flag to pass parameters to this command. In this case we're indicating the repository name (for which we're using our <code>repoName</code> variable) and setting <code>private</code> option to <code>false</code>, since we want our repo to be puiblic.</p>
<p>Lots of other config options are available in the API, so <a target="_blank" href="https://docs.github.com/en/rest/reference/repos#create-a-repository-for-the-authenticated-user">check the docs</a> for more info.</p>
<ul>
<li>After running this command, GitHub will prompt us to enter our <strong>private token</strong> for authentication.</li>
</ul>
<p>If you don't have a private token yet, you can generate it in GitHub in <strong>Settings &gt; Developer settings &gt; Personal access tokens</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/screenshot.png" alt="screenshot" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/screenshot_1.png" alt="screenshot_1" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/screenshot_2.png" alt="screenshot_2" width="600" height="400" loading="lazy"></p>
<ul>
<li>Cool, we're almost done now! What we need now is the <strong>remote URL</strong> of our newly created GitHub repo.</li>
</ul>
<p>To get that we're going to use curl and the GitHub API again, like this:</p>
<pre><code class="lang-plaintext">GIT_URL=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/coccagerman/"$repoName" | jq -r '.clone_url')
</code></pre>
<p>Here we're declaring a variable called <code>GIT_URL</code> and assigning it to whatever the following command returns.</p>
<p>The <code>-H</code> flag sets the header of our request.</p>
<p>Then we pass the GitHub API endpoint, which should contain our user name and repo name (<code>https://api.github.com/repos/coccagerman/"$repoName"</code>).</p>
<p>Then we're <strong>piping</strong> the return value of our request. Piping just means passing the return value of a process as the input value of another process. We can do it with the <code>|</code> symbol like <code>&lt;process1&gt; | &lt;process2&gt;</code>.</p>
<p>And finally we run the <code>jq</code> command, which is a tool for processing JSON inputs. Here we tell it to get the value of <code>.clone_url</code> which is where our remote git URL will be according to the data format provided by the GitHub API.</p>
<ul>
<li>And as last step, we rename our master branch to main, add the remote origin we just obtained, and push our code to GitHub! =D</li>
</ul>
<pre><code class="lang-plaintext">git branch -M main
git remote add origin $GIT_URL
git push -u origin main
</code></pre>
<p>Our full script should look something like this:</p>
<pre><code class="lang-plaintext">#! /bin/sh
repoName=$1

while [ -z "$repoName" ]
do
    echo 'Provide a repository name'
    read -r -p $'Repository name:' repoName
done

echo "# $repoName" &gt;&gt; README.md
git init
git add .
git commit -m "First commit"

curl -u &lt;yourUserName&gt; https://api.github.com/user/repos -d '{"name": "'"$repoName"'", "private":false}'

GIT_URL=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/&lt;yourUserName&gt;/"$repoName" | jq -r '.clone_url')

git branch -M main
git remote add origin $GIT_URL
git push -u origin main
</code></pre>
<ul>
<li>Now it's time to test our script! To <strong>execute</strong> it there're two things we can do.</li>
</ul>
<p>One option is to enter the shell name and pass the file as parameter, like: <code>dash ../ger/code/projects/scripts/newGhRepo.sh</code>.</p>
<p>And the other is to make the file <strong>executable</strong> by running <code>chmod u+x ../ger/code/projects/scripts/newGhRepo.sh</code>.</p>
<p>Then you can just execute the file directly by running <code>../ger/code/projects/scripts/newGhRepo.sh</code>.</p>
<p>And that's it! We have our script up and running. Everytime we need a new repo we can just execute this script from whatever directory we're in.</p>
<p>But there's something a bit annoying about this. We need to remember the exact route of the script directory. Wouldn't it be cool to execute the script with a single command that it's always the same independently of what directory we're at?</p>
<p>In come <strong>bash aliases</strong> to solve our problem.</p>
<p>Aliases are a way bash provides for making names for exact commands we want to run.</p>
<p>To create a new alias, we need to edit the bash configuration files in our system. This files are normally located in the home directory. Aliases can be defined in different files (mainly <code>.bashrc</code> or <code>.bash_aliases</code>).</p>
<p>I have a <code>.bash_aliases</code> file on my system, so let's edit that.</p>
<ul>
<li><p>In our CLI we enter <code>cd</code> to go over home directory.</p>
</li>
<li><p>Then we can enter <code>ls -a</code> to list all files (includen hidden ones) and check if we have either a <code>.bashrc</code> or <code>.bash_aliases</code> file in our system.</p>
</li>
<li><p>We open the file with our text/code editor of choice.</p>
</li>
<li><p>And we write our new alias like this: <code>alias newghrepo="dash /home/German/Desktop/ger/code/projects/scripts/newGhRepo.sh"</code></p>
</li>
</ul>
<p>Here I'm declaring the alias name, the actual command I'm going to enter to run the script (<code>newghrepo</code>).</p>
<p>And between quotes, define what that alias is going to do (<code>"dash /home/German/Desktop/ger/code/projects/scripts/newGhRepo.sh"</code>)</p>
<p>See that I'm passing the <a target="_blank" href="https://www.computerhope.com/issues/ch001708.htm">absolute path</a> of the script, so that this command works the same no matter what my current directory is.</p>
<p>If you don't know what the absolute path of your script is, go to the script directory on your terminal and enter <code>readlink -f newGhRepo.sh</code>. That should return the full path for you. ;)</p>
<ul>
<li>After we're done editing, we save our file, restart our terminal, and voilà! Now we can run our script by just entering <code>newghrepo</code>, no matter in what directory we currently are. Much quicker than opening the browser and clicking around to create our repo! =D</li>
</ul>
<p>I hope this gives you a little taste of the kind of optimizations that are possible with scripting. It certainly requires a bit more work the first time you write, test, and set up the script. But after that, you'll never have to perform that task manually again. ;)</p>
<h1 id="heading-round-up">Round up</h1>
<p>The terminal can feel like an intimidating and intricate place when you're starting out. But it's certainly worth it to put time and effort into learning the ins and outs of it. The efficiency benefits are too good to pass up!</p>
<blockquote>
<p>If you're interested in learning more about the terminal and Bash, Zach Gollwitzer has <a target="_blank" href="https://www.youtube.com/playlist?list=PLYQSCk-qyTW0d88jNocdi_YIFMA5Fnpug">an awesome crash course series on youtube</a>. He has also great tutorials on other topics such as Node and Javascript, so I recommend that you follow him. ;)</p>
</blockquote>
<p>As always, I hope you enjoyed the article and learned something new. If you want, you can also follow me on <a target="_blank" href="https://www.linkedin.com/in/germancocca/">linkedin</a> or <a target="_blank" href="https://twitter.com/CoccaGerman">twitter</a>.</p>
<p>Cheers and see you in the next one! =D</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/8ef61e333efccb5900cd117a4d64e8d3.gif" alt="8ef61e333efccb5900cd117a4d64e8d3" width="600" height="400" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Shell Scripting for Beginners – How to Write Bash Scripts in Linux ]]>
                </title>
                <description>
                    <![CDATA[ Shell scripting is an important part of process automation in Linux. Scripting helps you write a sequence of commands in a file and then execute them. This saves you time because you don't have to write certain commands again and again. You can perfo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/shell-scripting-crash-course-how-to-write-bash-scripts-in-linux/</link>
                <guid isPermaLink="false">66adea79f928a14f7c42c35b</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zaira Hira ]]>
                </dc:creator>
                <pubDate>Thu, 31 Mar 2022 19:26:38 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/remove-key-val.gif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Shell scripting is an important part of process automation in Linux. Scripting helps you write a sequence of commands in a file and then execute them.</p>
<p>This saves you time because you don't have to write certain commands again and again. You can perform daily tasks efficiently and even schedule them for automatic execution.</p>
<p>You can also set certain scripts to execute on startup such as showing a particular message on launching a new session or setting certain environment variables.</p>
<p>The applications and uses of scripting are numerous, so let's dive in.</p>
<p>In this article, you will learn:</p>
<ol>
<li><p>What is a bash shell?</p>
</li>
<li><p>What is a bash script and how do you identify it?</p>
</li>
<li><p>How to create your first bash script and execute it.</p>
</li>
<li><p>The basic syntax of shell scripting.</p>
</li>
<li><p>How to see a system's scheduled scripts.</p>
</li>
<li><p>How to automate scripts by scheduling via cron jobs.</p>
</li>
</ol>
<p>The best way to learn is by practicing. I highly encourage you to follow along using <a target="_blank" href="https://replit.com/~">Replit</a>. You can access a running Linux shell within minutes.</p>
<h2 id="heading-introduction-to-the-bash-shell">Introduction to the Bash Shell</h2>
<p>The Linux command line is provided by a program called the shell. Over the years, the shell program has evolved to cater to various options.</p>
<p>Different users can be configured to use different shells. But most users prefer to stick with the current default shell. The default shell for many Linux distros is the GNU Bourne-Again Shell (bash). Bash succeeded the Bourne shell (<code>sh</code>).</p>
<p>When you first launch the shell, it uses a startup script located in the <code>.bashrc</code> or <code>.bash_profile</code> file which allows you to customize the behavior of the shell.</p>
<p>When a shell is used interactively, it displays a <code>$</code> when it is waiting for a command from the user. This is called the shell prompt.</p>
<p><code>[username@host ~]$</code></p>
<p>If shell is running as root, the prompt is changed to <code>#</code>. The superuser shell prompt looks like this:</p>
<p><code>[root@host ~]#</code></p>
<p>Bash is very powerful as it can simplify certain operations that are hard to accomplish efficiently with a GUI. Remember that most servers do not have a GUI, and it is best to learn to use the powers of a command line interface (CLI).</p>
<h2 id="heading-what-is-a-bash-script">What is a Bash Script?</h2>
<p>A bash script is a series of commands written in a file. These are read and executed by the bash program. The program executes line by line.</p>
<p>For example, you can navigate to a certain path, create a folder and spawn a process inside it using the command line.</p>
<p>You can do the same sequence of steps by saving the commands in a bash script and running it. You can run the script any number of times.</p>
<h2 id="heading-how-do-you-identify-a-bash-script">How Do You Identify a Bash Script?</h2>
<h3 id="heading-file-extension-of-sh">File extension of <code>.sh</code>.</h3>
<p>By naming conventions, bash scripts end with a <code>.sh</code>. However, bash scripts can run perfectly fine without the <code>sh</code> extension.</p>
<h3 id="heading-scripts-start-with-a-bash-bang">Scripts start with a bash bang.</h3>
<p>Scripts are also identified with a <code>shebang</code>. Shebang is a combination of <code>bash #</code> and <code>bang !</code> followed the the bash shell path. This is the first line of the script. Shebang tells the shell to execute it via bash shell. Shebang is simply an absolute path to the bash interpreter.</p>
<p>Below is an example of the shebang statement.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#! /bin/bash</span>
</code></pre>
<p>The path of the bash program can vary. We will see later how to identify it.</p>
<h3 id="heading-execution-rights">Execution rights</h3>
<p>Scripts have execution rights for the user executing them.</p>
<p>An execution right is represented by <code>x</code>. In the example below, my user has the <code>rwx</code> (read, write, execute) rights for the file <code>test_script.sh</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-98.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-file-colour">File colour</h3>
<p>Executable scripts appear in a different colour from rest of the files and folders.</p>
<p>In my case, the scripts with execution rights appear as green.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-99.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-create-your-first-bash-script">How to Create Your First Bash Script</h2>
<p>Let's create a simple script in bash that outputs <code>Hello World</code>.</p>
<h3 id="heading-create-a-file-named-helloworldsh">Create a file named hello_world.sh</h3>
<pre><code class="lang-bash">touch hello_world.sh
</code></pre>
<h3 id="heading-find-the-path-to-your-bash-shell">Find the path to your bash shell.</h3>
<pre><code class="lang-bash"><span class="hljs-built_in">which</span> bash
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-100.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In my case, the path is <code>/usr/bin/bash</code> and I will include this in the shebang.</p>
<h3 id="heading-write-the-command">Write the command.</h3>
<p>We will <code>echo</code> "hello world" to the console.</p>
<p>Our script will look something like this:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#! /usr/bin/bash</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello World"</span>
</code></pre>
<p>Edit the file <code>hello_world.sh</code> using a text editor of your choice and add the above lines in it.</p>
<h3 id="heading-provide-execution-rights-to-your-user">Provide execution rights to your user.</h3>
<p>Modify the file permissions and allow execution of the script by using the command below:</p>
<pre><code class="lang-bash">chmod u+x hello_world.sh
</code></pre>
<p><code>chmod</code> modifies the existing rights of a file for a particular user. We are adding <code>+x</code> to user <code>u</code>.</p>
<h3 id="heading-run-the-script">Run the script.</h3>
<p>You can run the script in the following ways:</p>
<p><code>./hello_world.sh</code></p>
<p><code>bash hello_world.sh</code>.</p>
<p><strong>Here's the output:</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-160.png" alt="Two ways to run scripts" width="600" height="400" loading="lazy"></p>
<p><em>Two ways to run scripts</em></p>
<h2 id="heading-the-basic-syntax-of-bash-scripting">The Basic Syntax of Bash Scripting</h2>
<p>Just like any other programming language, bash scripting follows a set of rules to create programs understandable by the computer. In this section, we will study the syntax of bash scripting.</p>
<h3 id="heading-how-to-define-variables">How to define variables</h3>
<p>We can define a variable by using the syntax <code>variable_name=value</code>. To get the value of the variable, add <code>$</code> before the variable.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># A simple variable example</span>
greeting=Hello
name=Tux
<span class="hljs-built_in">echo</span> <span class="hljs-variable">$greeting</span> <span class="hljs-variable">$name</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-104.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Tux is also the name of the Linux mascot, the penguin.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-119.png" alt="Hi, I am Tux." width="600" height="400" loading="lazy"></p>
<p><em>Hi, I am Tux.</em></p>
<h3 id="heading-arithmetic-expressions">Arithmetic Expressions</h3>
<p>Below are the operators supported by bash for mathematical calculations:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Operator</td><td>Usage</td></tr>
</thead>
<tbody>
<tr>
<td>+</td><td>addition</td></tr>
<tr>
<td>-</td><td>subtraction</td></tr>
<tr>
<td>*</td><td>multiplication</td></tr>
<tr>
<td>/</td><td>division</td></tr>
<tr>
<td>**</td><td>exponentiation</td></tr>
<tr>
<td>%</td><td>modulus</td></tr>
</tbody>
</table>
</div><p>Let's run a few examples.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-108.png" alt="Note the spaces, these are part of the syntax" width="600" height="400" loading="lazy"></p>
<p><em>Note the spaces, these are part of the syntax</em></p>
<p>Numerical expressions can also be calculated and stored in a variable using the syntax below:</p>
<p><code>var=$((expression))</code></p>
<p>Let's try an example.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

var=$((<span class="hljs-number">3</span>+<span class="hljs-number">9</span>))
<span class="hljs-built_in">echo</span> <span class="hljs-variable">$var</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-109.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Fractions are not correctly calculated using the above methods and truncated.</p>
<p>For <strong>decimal calculations</strong>, we can use <code>bc</code> command to get the output to a particular number of decimal places. <code>bc</code> (Bash Calculator) is a command line calculator that supports calculation up to a certain number of decimal points.</p>
<p><code>echo "scale=2;22/7" | bc</code></p>
<p>Where <code>scale</code> defines the number of decimal places required in the output.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-110.png" alt="Getting output to 2 decimal places" width="600" height="400" loading="lazy"></p>
<p><em>Getting output to 2 decimal places</em></p>
<h3 id="heading-how-to-read-user-input">How to read user input</h3>
<p>Sometimes you'll need to gather user input and perform relevant operations.</p>
<p>In bash, we can take user input using the <code>read</code> command.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">read</span> variable_name
</code></pre>
<p>To prompt the user with a custom message, use the <code>-p</code> flag.</p>
<p><code>read -p "Enter your age" variable_name</code></p>
<p><strong>Example:</strong></p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Enter a numner"</span>
<span class="hljs-built_in">read</span> a

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Enter a numner"</span>
<span class="hljs-built_in">read</span> b

var=$((a+b))
<span class="hljs-built_in">echo</span> <span class="hljs-variable">$var</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-111.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-numeric-comparison-logical-operators">Numeric Comparison logical operators</h3>
<p>Comparison is used to check if statements evaluate to <code>true</code> or <code>false</code>. We can use the below shown operators to compare two statements:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Operation</td><td>Syntax</td><td>Explanation</td></tr>
</thead>
<tbody>
<tr>
<td>Equality</td><td>num1 -eq num2</td><td>is num1 equal to num2</td></tr>
<tr>
<td>Greater than equal to</td><td>num1 -ge num2</td><td>is num1 greater than equal to num2</td></tr>
<tr>
<td>Greater than</td><td>num1 -gt num2</td><td>is num1 greater than num2</td></tr>
<tr>
<td>Less than equal to</td><td>num1 -le num2</td><td>is num1 less than equal to num2</td></tr>
<tr>
<td>Less than</td><td>num1 -lt num2</td><td>is num1 less than num2</td></tr>
<tr>
<td>Not Equal to</td><td>num1 -ne num2</td><td>is num1 not equal to num2</td></tr>
</tbody>
</table>
</div><p><strong>Syntax</strong>:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">if</span> [ conditions ]
    <span class="hljs-keyword">then</span>
         commands
<span class="hljs-keyword">fi</span>
</code></pre>
<p><strong>Example</strong>:</p>
<p>Let's compare two numbers and find their relationship:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">read</span> x
<span class="hljs-built_in">read</span> y

<span class="hljs-keyword">if</span> [ <span class="hljs-variable">$x</span> -gt <span class="hljs-variable">$y</span> ]
<span class="hljs-keyword">then</span>
<span class="hljs-built_in">echo</span> X is greater than Y
<span class="hljs-keyword">elif</span> [ <span class="hljs-variable">$x</span> -lt <span class="hljs-variable">$y</span> ]
<span class="hljs-keyword">then</span>
<span class="hljs-built_in">echo</span> X is less than Y
<span class="hljs-keyword">elif</span> [ <span class="hljs-variable">$x</span> -eq <span class="hljs-variable">$y</span> ]
<span class="hljs-keyword">then</span>
<span class="hljs-built_in">echo</span> X is equal to Y
<span class="hljs-keyword">fi</span>
</code></pre>
<p>Output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-112.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-conditional-statements-decision-making">Conditional Statements (Decision Making)</h3>
<p>Conditions are expressions that evaluate to a boolean expression (<code>true</code> or <code>false</code>). To check conditions, we can use <code>if</code>, <code>if-else</code>, <code>if-elif-else</code> and nested conditionals.</p>
<p>The structure of conditional statements is as follows:</p>
<ul>
<li><p><code>if...then...fi</code> statements</p>
</li>
<li><p><code>if...then...else...fi</code> statements</p>
</li>
<li><p><code>if..elif..else..fi</code></p>
</li>
<li><p><code>if..then..else..if..then..fi..fi..</code> (Nested Conditionals)</p>
</li>
</ul>
<p><strong>Syntax</strong>:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">if</span> [[ condition ]]
<span class="hljs-keyword">then</span>
    statement
<span class="hljs-keyword">elif</span> [[ condition ]]; <span class="hljs-keyword">then</span>
    statement 
<span class="hljs-keyword">else</span>
    <span class="hljs-keyword">do</span> this by default
<span class="hljs-keyword">fi</span>
</code></pre>
<p>To create meaningful comparisons, we can use AND <code>-a</code> and OR <code>-o</code> as well.</p>
<p>The below statement translates to: If <code>a</code> is greater than 40 and <code>b</code> is less than 6.</p>
<p><code>if [ $a -gt 40 -a $b -lt 6 ]</code></p>
<p><strong>Example</strong>: Let's find the triangle type by reading the lengths of its sides.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">read</span> a
<span class="hljs-built_in">read</span> b
<span class="hljs-built_in">read</span> c

<span class="hljs-keyword">if</span> [ <span class="hljs-variable">$a</span> == <span class="hljs-variable">$b</span> -a <span class="hljs-variable">$b</span> == <span class="hljs-variable">$c</span> -a <span class="hljs-variable">$a</span> == <span class="hljs-variable">$c</span> ]
<span class="hljs-keyword">then</span>
<span class="hljs-built_in">echo</span> EQUILATERAL

<span class="hljs-keyword">elif</span> [ <span class="hljs-variable">$a</span> == <span class="hljs-variable">$b</span> -o <span class="hljs-variable">$b</span> == <span class="hljs-variable">$c</span> -o <span class="hljs-variable">$a</span> == <span class="hljs-variable">$c</span> ]
<span class="hljs-keyword">then</span> 
<span class="hljs-built_in">echo</span> ISOSCELES
<span class="hljs-keyword">else</span>
<span class="hljs-built_in">echo</span> SCALENE

<span class="hljs-keyword">fi</span>
</code></pre>
<p><strong>Output</strong>:</p>
<p>Test case #1</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-113.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Test case #2</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-114.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Test case #3</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-115.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-looping-and-skipping">Looping and skipping</h3>
<p>For loops allow you to execute statements a specific number of times.</p>
<h4 id="heading-looping-with-numbers">Looping with numbers:</h4>
<p>In the example below, the loop will iterate 5 times.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> {1..5}
<span class="hljs-keyword">do</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-variable">$i</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/Looping-with-numbers.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-looping-with-strings">Looping with strings:</h4>
<p>We can loop through strings as well.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-keyword">for</span> X <span class="hljs-keyword">in</span> cyan magenta yellow  
<span class="hljs-keyword">do</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-variable">$X</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/Looping-with-strings.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-while-loop">While loop</h4>
<p>While loops check for a condition and loop until the condition remains <code>true</code>. We need to provide a counter statement that increments the counter to control loop execution.</p>
<p>In the example below, <code>(( i += 1 ))</code> is the counter statement that increments the value of <code>i</code>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
i=1
<span class="hljs-keyword">while</span> [[ <span class="hljs-variable">$i</span> -le 10 ]] ; <span class="hljs-keyword">do</span>
   <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$i</span>"</span>
  (( i += 1 ))
<span class="hljs-keyword">done</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-153.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-reading-files">Reading files</h3>
<p>Suppose we have a file <code>sample_file.txt</code> as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-151.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We can read the file line by line and print the output on the screen.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

LINE=1

<span class="hljs-keyword">while</span> <span class="hljs-built_in">read</span> -r CURRENT_LINE
    <span class="hljs-keyword">do</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$LINE</span>: <span class="hljs-variable">$CURRENT_LINE</span>"</span>
    ((LINE++))
<span class="hljs-keyword">done</span> &lt; <span class="hljs-string">"sample_file.txt"</span>
</code></pre>
<p><strong>Output:</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-152.png" alt="Lines with line number printed" width="600" height="400" loading="lazy"></p>
<p><em>Lines with line number printed</em></p>
<h3 id="heading-how-to-execute-commands-with-back-ticks">How to execute commands with back ticks</h3>
<p>If you need to include the output of a complex command in your script, you can write the statement inside back ticks.</p>
<h4 id="heading-syntax">Syntax:</h4>
<p>var= commands</p>
<p><strong>Example</strong>: Suppose we want to get the output of a list of mountpoints with <code>tmpfs</code> in their name. We can craft a statement like this: <code>df -h | grep tmpfs</code>.</p>
<p>To include it in the bash script, we can enclose it in back ticks.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

var=`df -h | grep tmpfs`
<span class="hljs-built_in">echo</span> <span class="hljs-variable">$var</span>
</code></pre>
<p>Output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-118.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-get-arguments-for-scripts-from-the-command-line">How to get arguments for scripts from the command line</h3>
<p>It is possible to give arguments to the script on execution.</p>
<p><code>$@</code> represents the position of the parameters, starting from one.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-variable">$@</span>
<span class="hljs-keyword">do</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"Entered arg is <span class="hljs-variable">$x</span>"</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p>Run it like this:</p>
<p><code>./script arg1 arg2</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-155.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-automate-scripts-by-scheduling-via-cron-jobs">How to Automate Scripts by Scheduling via cron Jobs</h2>
<p>Cron is a job scheduling utility present in Unix like systems. You can schedule jobs to execute daily, weekly, monthly or in a specific time of the day. Automation in Linux heavily relies on cron jobs.</p>
<p>Below is the syntax to schedule crons:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Cron job example</span>
* * * * * sh /path/to/script.sh
</code></pre>
<p>Here, <code>*</code> represents minute(s) hour(s) day(s) month(s) weekday(s), respectively.</p>
<p>Below are some examples of scheduling cron jobs.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>SCHEDULE</td><td>SCHEDULED VALUE</td></tr>
</thead>
<tbody>
<tr>
<td>5 0 * 8 *</td><td>At 00:05 in August.</td></tr>
<tr>
<td>5 4 * * 6</td><td>At 04:05 on Saturday.</td></tr>
<tr>
<td>0 22 * * 1-5</td><td>At 22:00 on every day-of-week from Monday through Friday.</td></tr>
</tbody>
</table>
</div><p>You can learn about cron in detail in this <a target="_blank" href="https://www.freecodecamp.org/news/cron-jobs-in-linux/">blog</a> post.</p>
<h2 id="heading-how-to-check-existing-scripts-in-a-system">How to Check Existing Scripts in a System</h2>
<h3 id="heading-using-crontab">Using crontab</h3>
<p><code>crontab -l</code> lists the already scheduled scripts for a particular user.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-103.png" alt="My scheduled scripts" width="600" height="400" loading="lazy"></p>
<p><em>My scheduled scripts</em></p>
<h3 id="heading-using-the-find-command">Using the find command</h3>
<p>The <code>find</code> command helps to locate files based on certain patterns. As most of the scripts end with <code>.sh</code>, we can use the find script like this:</p>
<pre><code class="lang-bash">find . -<span class="hljs-built_in">type</span> f -name <span class="hljs-string">"*.sh"</span>
</code></pre>
<p>Where,</p>
<ul>
<li><p><code>.</code> represents the current directory. You can change the path accordingly.</p>
</li>
<li><p><code>-type f</code> indicates that the file type we are looking for is a text based file.</p>
</li>
<li><p><code>*.sh</code> tells to match all files ending with <code>.sh</code>.</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-159.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you are interested to read about the find command in detail, check <a target="_blank" href="https://www.freecodecamp.org/news/how-to-search-for-files-from-the-linux-command-line/">my other post</a>.</p>
<h2 id="heading-wrapping-up"><strong>Wrapping up</strong></h2>
<p>In this tutorial we learned the basics of shell scripting. We looked into examples and syntax which can help us write meaningful programs.</p>
<p>What’s your favorite thing you learned from this tutorial? Let me know on <a target="_blank" href="https://twitter.com/hira_zaira">Twitter</a>!</p>
<p>You can read my other posts <a target="_blank" href="https://www.freecodecamp.org/news/author/zaira/">here</a>.</p>
<p><a target="_blank" href="https://www.freepik.com/vectors/work">Work vector created by macrovector - www.freepik.com</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
