<?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[ shell script - 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[ shell script - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 23 Jun 2026 21:16:03 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/shell-script/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <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[ Run Python Script – How to Execute Python Shell Commands in the Terminal ]]>
                </title>
                <description>
                    <![CDATA[ By Suchandra Datta When you're starting out learning a new programming language, your very first program is likely to be one that prints "hello world!".  Let's say you want to do this in Python. There are two ways of doing it: using the Python shell ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/run-python-script-how-to-execute-python-shell-commands-in-terminal/</link>
                <guid isPermaLink="false">66d8526f981549ab9e803f14</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 14 Jul 2022 15:24:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/pexels-jan-kopr-iva-3280908.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Suchandra Datta</p>
<p>When you're starting out learning a new programming language, your very first program is likely to be one that prints "hello world!". </p>
<p>Let's say you want to do this in Python. There are two ways of doing it: using the Python shell or writing it as a script and running it in the terminal. </p>
<h2 id="heading-what-is-a-shell">What is a Shell?</h2>
<p>An operating system is made up of a bunch of programs. They perform tasks like file handling, memory management, and resource management, and they help your applications run smoothly. </p>
<p>All the work we do on computers, like analyzing data in Excel or playing games, is facilitated by the operating system. </p>
<p>Operating system programs are of two types, called <strong>shell</strong> and <strong>kernel</strong> programs.</p>
<p>Kernel programs are the ones who perform the actual tasks, like creating a file or sending interrupts. Shell is another program, whose job is to take input and decide and execute the required kernel program to do the job and show the output. </p>
<p>The shell is also called the <strong>command processor</strong>. </p>
<h2 id="heading-what-is-a-terminal">What is a Terminal?</h2>
<p>The terminal is the program that interacts with the shell and allows us to communicate with it via text-based commands. This is why it's also called the command line. </p>
<p>To access the terminal on Windows, hit the Windows logo + R, type cmd, and press Enter.</p>
<p>To access the terminal on Ubuntu, hit Ctrl + Alt + T.</p>
<h2 id="heading-what-is-the-python-shell">What is the Python Shell?</h2>
<p>Python is an interpreted language. This means that the Python interpreter reads a line of code, executes that line, then repeats this process if there are no errors. </p>
<p>The Python Shell gives you a command line interface you can use to specify commands directly to the Python interpreter in an interactive manner. </p>
<p>You can get a lot of detailed information regarding the Python shell in the <a target="_blank" href="https://docs.python.org/3/tutorial/interpreter.html#">official docs</a>.</p>
<h2 id="heading-how-to-use-the-python-shell">How to Use the Python Shell</h2>
<p>To start the Python shell, simply type <code>python</code> and hit Enter in the terminal:</p>
<pre><code>C:\Users\Suchandra Datta&gt;python
Python <span class="hljs-number">3.8</span><span class="hljs-number">.3</span> (tags/v3<span class="hljs-number">.8</span><span class="hljs-number">.3</span>:<span class="hljs-number">6</span>f8c832, May <span class="hljs-number">13</span> <span class="hljs-number">2020</span>, <span class="hljs-number">22</span>:<span class="hljs-number">37</span>:<span class="hljs-number">02</span>) [MSC v<span class="hljs-number">.1924</span> <span class="hljs-number">64</span> bit (AMD64)] on win32
Type <span class="hljs-string">"help"</span>, <span class="hljs-string">"copyright"</span>, <span class="hljs-string">"credits"</span> or <span class="hljs-string">"license"</span> <span class="hljs-keyword">for</span> more information.
&gt;&gt;&gt;print(<span class="hljs-string">"hello world!"</span>)
</code></pre><p>The interactive shell is also called REPL which stands for read, evaluate, print, loop. It'll read each command, evaluate and execute it, print the output for that command if any, and continue this same process repeatedly until you quit the shell. </p>
<p>There are different ways to quit the shell:</p>
<ul>
<li>you can hit Ctrl+Z on Windows or Ctrl+D on Unix systems to quit</li>
<li>use the exit() command</li>
<li>use the quit() command</li>
</ul>
<pre><code>C:\Users\Suchandra Datta&gt;python
Python <span class="hljs-number">3.8</span><span class="hljs-number">.3</span> (tags/v3<span class="hljs-number">.8</span><span class="hljs-number">.3</span>:<span class="hljs-number">6</span>f8c832, May <span class="hljs-number">13</span> <span class="hljs-number">2020</span>, <span class="hljs-number">22</span>:<span class="hljs-number">37</span>:<span class="hljs-number">02</span>) [MSC v<span class="hljs-number">.1924</span> <span class="hljs-number">64</span> bit (AMD64)] on win32
Type <span class="hljs-string">"help"</span>, <span class="hljs-string">"copyright"</span>, <span class="hljs-string">"credits"</span> or <span class="hljs-string">"license"</span> <span class="hljs-keyword">for</span> more information.
&gt;&gt;&gt; print(<span class="hljs-string">"HELLO WORLD"</span>)
HELLO WORLD
&gt;&gt;&gt; quit()

<span class="hljs-attr">C</span>:\Users\Suchandra Datta&gt;
</code></pre><pre><code>C:\Users\Suchandra Datta&gt;python
Python <span class="hljs-number">3.8</span><span class="hljs-number">.3</span> (tags/v3<span class="hljs-number">.8</span><span class="hljs-number">.3</span>:<span class="hljs-number">6</span>f8c832, May <span class="hljs-number">13</span> <span class="hljs-number">2020</span>, <span class="hljs-number">22</span>:<span class="hljs-number">37</span>:<span class="hljs-number">02</span>) [MSC v<span class="hljs-number">.1924</span> <span class="hljs-number">64</span> bit (AMD64)] on win32
Type <span class="hljs-string">"help"</span>, <span class="hljs-string">"copyright"</span>, <span class="hljs-string">"credits"</span> or <span class="hljs-string">"license"</span> <span class="hljs-keyword">for</span> more information.
&gt;&gt;&gt; exit()

<span class="hljs-attr">C</span>:\Users\Suchandra Datta&gt;
</code></pre><pre><code>C:\Users\Suchandra Datta&gt;python
Python <span class="hljs-number">3.8</span><span class="hljs-number">.3</span> (tags/v3<span class="hljs-number">.8</span><span class="hljs-number">.3</span>:<span class="hljs-number">6</span>f8c832, May <span class="hljs-number">13</span> <span class="hljs-number">2020</span>, <span class="hljs-number">22</span>:<span class="hljs-number">37</span>:<span class="hljs-number">02</span>) [MSC v<span class="hljs-number">.1924</span> <span class="hljs-number">64</span> bit (AMD64)] on win32
Type <span class="hljs-string">"help"</span>, <span class="hljs-string">"copyright"</span>, <span class="hljs-string">"credits"</span> or <span class="hljs-string">"license"</span> <span class="hljs-keyword">for</span> more information.
&gt;&gt;&gt; ^Z


<span class="hljs-attr">C</span>:\Users\Suchandra Datta&gt;
</code></pre><h2 id="heading-what-can-you-do-in-the-python-shell">What Can You Do in the Python Shell?</h2>
<p>You can do pretty much everything that the Python language allows, from using variables, loops, and conditions to defining functions and more. </p>
<p>The <code>&gt;&gt;&gt;</code> is the shell prompt where you type in your commands. If you have commands that span across several lines – for example when you define loops – the shell prints the <code>...</code> characters which signifies that a line continues.</p>
<p>Let's see an example:</p>
<pre><code>&gt;&gt;&gt;
&gt;&gt;&gt; watch_list = [<span class="hljs-string">"stranger_things_s1"</span>, <span class="hljs-string">"stranger_things_s2"</span>, <span class="hljs-string">"stranger_things_s3"</span>,<span class="hljs-string">"stranger_things_s4"</span>]
&gt;&gt;&gt;
&gt;&gt;&gt;
</code></pre><p>Here we defined a list with some TV show names via the Python shell.</p>
<p>Next, let's define a function that accepts a list of shows and randomly returns a show:</p>
<pre><code>&gt;&gt;&gt; def weekend_party(show_list):
...     r = random.randint(<span class="hljs-number">0</span>, len(show_list)<span class="hljs-number">-1</span>)
...     return show_list[r]
...
</code></pre><p>Note the continuation lines (<code>...</code>) of the Python shell here.</p>
<p>Finally to invoke the function from the shell, you simply call the function the way you would do in a script:</p>
<pre><code>&gt;&gt;&gt; weekend_party(watch_list)
<span class="hljs-string">'stranger_things_s1'</span>
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; weekend_party(watch_list)
<span class="hljs-string">'stranger_things_s3'</span>
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; weekend_party(watch_list)
<span class="hljs-string">'stranger_things_s2'</span>
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; weekend_party(watch_list)
<span class="hljs-string">'stranger_things_s2'</span>
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; weekend_party(watch_list)
<span class="hljs-string">'stranger_things_s3'</span>
&gt;&gt;&gt;
</code></pre><p>You can inspect Python modules from the shell, as shown below:</p>
<pre><code>&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; <span class="hljs-keyword">import</span> numpy
&gt;&gt;&gt; numpy.__version__
<span class="hljs-string">'1.20.1'</span>
&gt;&gt;&gt;
</code></pre><p>You can see what methods and attributes a module offers by using the <code>dir()</code> method:</p>
<pre><code>&gt;&gt;&gt;
&gt;&gt;&gt; x = dir(numpy)
&gt;&gt;&gt; len(x)
<span class="hljs-number">606</span>
&gt;&gt;&gt; x[<span class="hljs-number">0</span>:<span class="hljs-number">3</span>]
[<span class="hljs-string">'ALLOW_THREADS'</span>, <span class="hljs-string">'AxisError'</span>, <span class="hljs-string">'BUFSIZE'</span>]
</code></pre><p>Here you can see that Numpy has 606 methods and properties in total.</p>
<h2 id="heading-how-to-run-python-scripts">How to Run Python Scripts</h2>
<p>The Python shell is useful for executing simple programs or for debugging parts of complex programs. </p>
<p>But really large Python programs with a lot of complexity are written in files with a .py extension, typically called Python scripts. Then you execute them from the terminal using the <code>Python</code> command. </p>
<p>The usual syntax is:</p>
<pre><code>python filename.py
</code></pre><p>All the commands we executed previously via the shell, we can also write it in a script and run in this way. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we learnt about the shell, terminal, how to use the Python shell. We also saw how to run Python scripts from the command line.</p>
<p>I hope this article helps you understand what the Python shell is and how you can use it in your day to day lives. Happy learning!</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>
        
            <item>
                <title>
                    <![CDATA[ Dotfiles – What is a Dotfile and How to Create it in Mac and Linux ]]>
                </title>
                <description>
                    <![CDATA[ Dotfiles are important files that will play an integral role in your career as a software developer. First, they can help make you more productive. But not only that - you'll be able to have that productive setup you created for youself on any machin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/dotfiles-what-is-a-dot-file-and-how-to-create-it-in-mac-and-linux/</link>
                <guid isPermaLink="false">66b1e3f50938e6258a76bbca</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                    <category>
                        <![CDATA[ macOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ zsh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dionysia Lemonaki ]]>
                </dc:creator>
                <pubDate>Thu, 21 Oct 2021 19:49:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/10/dmitry-ratushny-xsGApcVbojU-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Dotfiles are important files that will play an integral role in your career as a software developer.</p>
<p>First, they can help make you more productive. But not only that - you'll be able to have that productive setup you created for youself on any machine.</p>
<p>This article is an introduction on how to get started with dotfiles.</p>
<p>You'll learn what they are, how to locate them on your system, and how to create a couple of simple dotfiles. In addition I'll give you some suggestions and resources on how to customise your settings and expand your knowledge.</p>
<p>Let's get started!</p>
<h2 id="heading-what-are-dotfiles">What are dotfiles?</h2>
<p>Many computer software programs store their configuration settings in plain, text-based files or directories.</p>
<p>Dotfiles are configuration files for various programs, and they help those programs manage their functionality.</p>
<p>What sets them apart from regular files and directories is their prefix. </p>
<p>Dotfiles are named that way because each file and directory starts with a dot (<code>.</code>)</p>
<p>On Unix based systems, dotfiles are hidden by the Operating System by default.</p>
<h3 id="heading-examples-of-common-dotfiles">Examples of common dotfiles</h3>
<p>Most programs store their configurations in your home directory by default.</p>
<p>Some common dotfiles that you may have heard of or used before are:</p>
<ul>
<li>If you use the Bash shell, you might have a <code>.bash_profile</code> and <code>.bashrc</code> file, both of which contain scripts that load each time you start a new terminal session and configure the shell.</li>
<li>If you use the Zsh shell, which is the new default for MacOS, you would have (or would've created) a <code>.zshrc</code> file which configures and customises the shell.</li>
<li>If you use the command line code editor Vim, you would store its configurations in a <code>.vimrc</code> file.</li>
<li>After setting up and configuring Git on your local machine, you would have a <code>.gitconfig</code> file, which would contain all your information and settings.</li>
<li>Many programs, instead of storing their configurations in your home directory, instead store them in the hidden <code>.config</code> directory (folder) on your system.</li>
</ul>
<h2 id="heading-how-to-find-dotfiles">How to Find Dotfiles</h2>
<p>In Finder, the root of your Home directory might look something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-20-at-7.11.45-PM.png" alt="Screenshot-2021-10-20-at-7.11.45-PM" width="600" height="400" loading="lazy"></p>
<p>But you've seen that computer systems have many more files stored which are hidden by default.</p>
<p>To view dotfiles in Finder, go to the root of your Home directory and hold down the keys <code>Command Shift .</code> and the same time. </p>
<p>You'll soon see a variety of dotfiles that either you created on your own or were created when you installed a piece of software.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-20-at-7.12.04-PM.png" alt="Screenshot-2021-10-20-at-7.12.04-PM" width="600" height="400" loading="lazy"></p>
<p>To view dotfiles from the command line (which is where you'll use and interact with them the most), you again have to add some extra steps to your search.</p>
<p>The list command, <code>ls</code>, which lists all files and directories in the current directory, doesn't show dotfiles by default - despite the fact that they're  there.</p>
<p>First, navigate to your home directory. You can use the <code>cd</code> command to help you get there, if you're not there already.</p>
<p>Then use the <code>ls</code> command with the <code>-a</code> flag, which stands for <code>all</code>, like so:</p>
<pre><code class="lang-shell">ls -a
</code></pre>
<p>If you want to see some extra bits of information about your files, you can also use the <code>-l</code> flag, which lists files and directories in long format and includes details about the date and time they were created, their size, and so on.</p>
<pre><code class="lang-shell">ls -la
</code></pre>
<p>In the output, you'll see all files and directories – inlcuding all hidden ones – in your currect home directory.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-19-at-1.37.15-PM.png" alt="Screenshot-2021-10-19-at-1.37.15-PM" width="600" height="400" loading="lazy"></p>
<p>Each file and directory that starts with a period/dot is a dotfile.</p>
<h2 id="heading-why-use-dotfiles">Why Use Dotfiles?</h2>
<p>Your dotfiles are personal to you.</p>
<p>You spend a sufficient amount of time fine-tuning your setup. You curate configurations and settings that best suit your workflow, aesthetic, and preferences. And you end up with a development environment that helps you, personally, be more productive.</p>
<p>What if after all that time you spent, you now have to switch to a new, different machine? Does that mean you have to start all over again from the beginning?</p>
<p>How would you remember the exact settings and commands you used?</p>
<p>Or what if you have a second machine and you want your set up to be exactly the same on both systems?</p>
<p>One of the main goals of developers is to automate repetitive tasks.</p>
<p>Creating a dotfile repository that is source-controlled and hosted on GitHub will save you time when you want to set up a new computer and install the exact same settings you created for your previous one.</p>
<p>That way all your settings and preferences can be reusable and consistent on other machines.</p>
<h2 id="heading-how-to-create-dotfiles">How to Create Dotfiles</h2>
<h3 id="heading-how-to-set-up-a-folder-to-hold-your-dotfiles">How to set up a folder to hold your dotfiles</h3>
<p>It's good practice to have all your dotfiles in their own folder.</p>
<p>For simplicity's sake, I'll show an example of how to create a folder at the root of your home directory. But you can add the folder wherever is more convenient for you. </p>
<p>Also, I'll be showing examples of how to create a <code>.zshrc</code> and <code>.vimrc</code> file, but similar ideas apply to any other dotfiles you create.</p>
<p>Navigate to your home directory (<code>cd</code>) and make a directory named <code>dotfiles</code> that will hold all your configuration files:</p>
<pre><code class="lang-shell">mkdir dotfiles
</code></pre>
<p>To create dotfiles, you use the <code>touch</code> command and pass the name(s) of the file(s) as the argument to the command. The filename(s) will have a preceding period.</p>
<p>To create a <code>.zshrc</code> and a <code>.vimrc</code> file in the <code>dotfiles</code> directory, do this:</p>
<pre><code class="lang-shell">touch ~/dotfiles/.zshrc  ~/dotfiles/.vimrc
</code></pre>
<p>If those files already exist on your system and you want to move them to the <code>dotfiles</code> directory, you can move them there using the <code>mv</code> command:</p>
<pre><code class="lang-shell">mv ~/.zshrc ~/dotfiles/
</code></pre>
<p>The first argument is the current path of the file – the tilde (<code>~</code>) stands for the home direcory. By default, most hidden confuguration files are located there.</p>
<p>The second argument is the path where you want to move the file to. In this case you want to move it to the the dotfiles directory that is located in the home directory.</p>
<p>You can do the same for the <code>.vimrc</code> file:</p>
<pre><code class="lang-shell">mv ~/.vimrc ~/dotfiles/
</code></pre>
<p>To view the files:</p>
<pre><code class="lang-shell">ls -a dotfiles 
.         ..     .vimrc    .zshrc
</code></pre>
<p>With those files in place you can then add all your preferred configurations there.</p>
<h3 id="heading-how-to-set-up-configurations">How to set up configurations</h3>
<p>Below are some ideas that could help you start the configurations of the dotfiles you created.</p>
<h4 id="heading-how-to-personalise-your-zsh-prompt">How to personalise your Zsh prompt</h4>
<p>After setting up the <code>.zshrc</code> file, anything added to that file will affect the customisation of your Zsh shell program.</p>
<p>Now could be the time to customise your shell prompt. This will be personal to your taste, but here are some resources to get you started:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-configure-your-macos-terminal-with-zsh-like-a-pro-c0ab3f3c1156/">How to customize your zsh prompt like a pro</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/jazz-up-your-zsh-terminal-in-seven-steps-a-visual-guide-e81a8fd59a38/">Jazz up your zsh terminal in seven steps</a></li>
<li><a target="_blank" href="https://scriptingosx.com/2019/07/moving-to-zsh-06-customizing-the-zsh-prompt/">More ideas to customize the zsh prompt</a></li>
<li><a target="_blank" href="https://www.makeuseof.com/customize-zsh-prompt-macos-terminal/">How to Customize the zsh Prompt in the macOS Terminal</a></li>
</ul>
<h4 id="heading-how-to-customise-vim">How to customise Vim</h4>
<p>After creating the <code>.vimrc</code> file, you can customise the command line text editor Vim. Here are a couple of resources to help you start that process:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/vimrc-configuration-guide-customize-your-vim-editor/">Vimrc Configuration Guide</a></li>
<li><a target="_blank" href="https://www.makeuseof.com/tag/5-things-need-put-vim-config-file/">How to Make Vim Look Good: 5 Vim Customization Tips</a></li>
</ul>
<h4 id="heading-what-are-aliases-and-functions">What are aliases and functions</h4>
<p>One way to improve your workflow and enhance your productivity, is to cut down the time it takes to type commands you use often. You can achieve that by creating shortcuts.</p>
<p>Aliases are shortcuts to terminal commands. They are a shorter version of a long command.</p>
<p>As a developer you'll use Git often, so it's a good idea to create Git aliases to help save time on long, repetitive Git commands. <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-git-aliases/">Have a read on some of the most helpful ones on this freeCodeCamp article</a>.</p>
<p>Another way to save time is by simplifying processes. </p>
<p>You can combine two commands into one by creating an isolated behavior that does one specific job. You can do that by creating functions.</p>
<p>One helpful function to create is to combine the command for creating a new directory (<code>mkdir</code>) with the command to change directory (<code>cd</code>). </p>
<p>In this way, you will create a new folder and immediately change into it – all in one step.</p>
<p>The function to do so looks like this:</p>
<pre><code class="lang-shell">function mkcd() {
  mkdir -p "$@" &amp;&amp; cd "$_";
}
</code></pre>
<p>To read up on Zsh, functions have a look at <a target="_blank" href="https://scriptingosx.com/2019/07/moving-to-zsh-part-4-aliases-and-functions/">this article on Scripting OS X that covers both aliases and functions in Zsh</a>.</p>
<p>You can add both aliases and functions to your <code>.zshrc</code> file or you can create separate <code>.aliases</code> and <code>.functions</code> dotfiles.</p>
<h2 id="heading-how-to-symlink-your-dotfiles">How to Symlink your Dotfiles</h2>
<p>You may have noticed that none of the settings you added to the files in the <code>dotfiles</code> folder have any effect on your system.</p>
<p>A program's configuration files, as mentioned previously, are hidden and stored in the home directory by default. This is where the program will look for and read its settings from.</p>
<p>It's a good idea to symlink (or create a symbolic link -a pointer) the file in the <code>dotfiles</code> directory where you have stored your preferred settings alongside with other files you created, with the file in its default home directory.</p>
<p>It's like the file will be in two places at the same time!</p>
<p>The file will be in both the <code>dotfiles</code> directory and there will also be a 'copy' of it in the home directory.</p>
<p>To create a link, you use the <code>ln</code> (stands for link) command with the <code>-s</code> argument (which stands for symbolic).</p>
<p>Here's how to symlink the <code>.zshrc</code> and <code>.vimrc</code> files:</p>
<pre><code class="lang-shell">ln -s ~/dotfiles/.vimrc  ~/.vimrc
ln -s ~/dotfiles/.zshrc  ~/.zshrc
</code></pre>
<p>This will make the programs you use aware of where their configuration files are normally – back in the home directory.</p>
<pre><code class="lang-shell">ls -l ~/.zshrc 

lrwxr-xr-x  1 dionysialemonaki  staff  39 Oct 21 18:30 /Users/dionysialemonaki/.zshrc -&gt; /Users/dionysialemonaki/dotfiles/.zshrc
</code></pre>
<p>Looking at the details of the <code>.zshrc</code> file, it shows that the file located in the home directory points to the file in the dotfiles directory. The <code>-&gt;</code> indicates the symlink.</p>
<p>Symlinking all your dotfiles manually is a cumbersome process and can get tiring and repetitive quickly as you add more dotfiles to the folder.</p>
<p>To make the process easier, you can create a shell script that will automate calling <code>ln -s</code> on the dotfiles you create or use a <a target="_blank" href="http://dotfiles.github.io/utilities/">utility</a> for that job.</p>
<h2 id="heading-how-to-version-control-your-dotfiles">How to Version Control your Dotfiles</h2>
<p>Having your files under version control will help you track all the changes you make to them over time, and will also allow you to share them on GitHub.</p>
<p>Make sure to change directory into the <code>dotfiles</code> directory (<code>cd dotfiles</code>).</p>
<p>Follow these steps to organise your files in a git repository:</p>
<ol>
<li>Initialise the repository:</li>
</ol>
<pre><code class="lang-shell">git init
</code></pre>
<ol start="2">
<li>Add all the files you've created so far:</li>
</ol>
<pre><code class="lang-shell">git add .
</code></pre>
<ol start="3">
<li>Commit the changes and add a commit message:</li>
</ol>
<pre><code class="lang-shell">git commit -m "Added dotfiles"
</code></pre>
<h3 id="heading-how-to-host-your-dotfiles-on-github">How to host your dotfiles on GitHub</h3>
<p>Make sure you've signed into your GitHub account.</p>
<p>Then, create a new repository:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-21-at-5.21.59-PM.png" alt="Screenshot-2021-10-21-at-5.21.59-PM" width="600" height="400" loading="lazy"></p>
<p>Give it a name add click "Create repository".</p>
<p>Next, in the command line, add:</p>
<pre><code class="lang-shell">git remote add origin url 

#where 'url',the GitHub url of the repository you previously created
#ending in .git
</code></pre>
<p>Finally,</p>
<pre><code class="lang-shell">git push -u origin main
</code></pre>
<p>And now you are able to share your dotfiles online!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>And there you have it – you now know the basics of dotfiles! I hope you found this tutorial helpful.</p>
<p>Your dotfiles project will most likely follow you throughout your career and will grow the more you learn about dotfiles themselves. And it'll also change as you learn more about what you like and don't like regarding your workflow and development environment setting by lots of trial and error.</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Bash Sleep – How to Make a Shell Script Wait N Seconds (Example Command) ]]>
                </title>
                <description>
                    <![CDATA[ By Veronica Stork When you're writing a shell script, you may find that you need it to wait a certain number of seconds before proceeding. For example, you might want the script to wait while a process completes or before retrying a failed command.  ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bash-sleep-how-to-make-a-shell-script-wait-n-seconds-example-command/</link>
                <guid isPermaLink="false">66d46173a326133d12440a96</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 13 Sep 2021 14:29:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/09/pexels-----------------------1560424.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Veronica Stork</p>
<p>When you're writing a shell script, you may find that you need it to wait a certain number of seconds before proceeding. For example, you might want the script to wait while a process completes or before retrying a failed command. </p>
<p>To do this, you can use the very straightforward <code>sleep</code> command. </p>
<h2 id="heading-how-to-use-the-bash-sleep-command">How to Use the Bash Sleep Command</h2>
<p><code>Sleep</code>  is a very versatile command with a very simple syntax. It is as easy as typing <code>sleep N</code>. This will pause your script for <code>N</code> seconds, with <code>N</code> being either a positive integer or a floating point number. </p>
<p>Consider this basic example:</p>
<pre><code>echo <span class="hljs-string">"Hello there!"</span>
sleep <span class="hljs-number">2</span>
echo <span class="hljs-string">"Oops! I fell asleep for a couple seconds!"</span>
</code></pre><p>The result of this script will look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/09/2021-09-10-22.33.49.gif" alt="gif of script running" width="600" height="400" loading="lazy"></p>
<p>Similarly, you could use a floating point number to represent fractions of seconds. For example, <code>sleep .8</code> will pause your script for .8 seconds. </p>
<p>That's it for the basic usage of the <code>sleep</code> command! </p>
<h2 id="heading-what-to-keep-in-mind-when-using-the-sleep-command">What to Keep in Mind When Using the Sleep Command</h2>
<p><code>Sleep</code>'s default unit of time is <strong>seconds</strong>, which is why we don't have to specify a unit in the examples above. </p>
<p>On some types of machines (namely BSD systems and MacOS,) the <em>only</em> unit of time supported is seconds. Other Unix-like operating systems will likely support the following units of time:</p>
<ul>
<li><code>s</code>: seconds</li>
<li><code>m</code>: minutes</li>
<li><code>h</code>: hours</li>
<li><code>d</code>: days</li>
</ul>
<p>It is also possible to use more than one argument with the <code>sleep</code> command. If there are two or more numbers included, the system will wait for the amount of time equivalent to the sum of those numbers.</p>
<p>For example, <code>sleep 2m 30s</code> will create a pause of 2 and a half minutes. Note that to achieve the same result on a MacOS or BSD machine, you would run the equivalent command <code>sleep 150</code>, as 2 minutes and 30 seconds is equal to 150 seconds. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The <code>sleep</code> command is a useful way to add pauses in your Bash script. Used in conjunction with other commands, <code>sleep</code> can help you create a timed alarm, run operations in the correct order, space out attempts to connect to a website, and more. So put this simple yet powerful tool in your Bash toolbox and code on!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Bashrc Customization Guide – How to Add Aliases, Use Functions, and More ]]>
                </title>
                <description>
                    <![CDATA[ By Brandon Wallace Customizing your .bashrc file can greatly improve your workflow and increase your productivity.  The .bashrc is a standard file located in your Linux home directory. In this article I will show you useful .bashrc options, aliases, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bashrc-customization-guide/</link>
                <guid isPermaLink="false">66d84e4e29e30bc0ad477555</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ unix ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 17 Mar 2021 22:40:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/03/bashrc_cover_image2-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Brandon Wallace</p>
<p>Customizing your .bashrc file can greatly improve your workflow and increase your productivity. </p>
<p>The .bashrc is a standard file located in your Linux home directory. In this article I will show you useful .bashrc options, aliases, functions, and more.</p>
<p>The main benefits of configuring the .bashrc file are:</p>
<ul>
<li>Adding aliases allows you to type commands faster, saving you time.</li>
<li>Adding functions allows you to save and rerun complex code.</li>
<li>It displays useful system information.</li>
<li>It customizes the Bash prompt.</li>
</ul>
<h2 id="heading-how-to-get-started-with-editing-bashrc">How to Get Started with Editing .bashrc</h2>
<p>Here's how you can edit the .bashrc file with a text editor:</p>
<pre><code class="lang-bash">$ vim ~/.bashrc
</code></pre>
<p>You can add date and time formatting to bash history.</p>
<pre><code class="lang-bash">HISTTIMEFORMAT=<span class="hljs-string">"%F %T "</span>
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Output</span>

$ <span class="hljs-built_in">history</span>
 1017  20210228 10:51:28  uptime
 1019  20210228 10:52:42  free -m
 1020  20210228 10:52:49  tree --dirsfirst -F
 1018  20210228 10:51:38  xrandr | awk <span class="hljs-string">'/\*/{print $1}'</span>
</code></pre>
<p>Add this line to ignore duplicate commands in the history.</p>
<pre><code class="lang-bash">HISTCONTROL=ignoredups
</code></pre>
<p>To set the number of lines in active history and to set the number of lines saved in Bash history, add these two lines.</p>
<pre><code class="lang-bash">HISTSIZE=2000
HISTFILESIZE=2000
</code></pre>
<p>You can set your history to append instead of overwriting Bash history. <strong><code>shopt</code></strong> stands for "shell options". </p>
<pre><code class="lang-bash"><span class="hljs-built_in">shopt</span> -s histappend
</code></pre>
<p>To see all the default shell options, run <code>shopt -p</code>.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Output</span>

$ <span class="hljs-built_in">shopt</span> -p

<span class="hljs-built_in">shopt</span> -u autocd                   
<span class="hljs-built_in">shopt</span> -u assoc_expand_once        
<span class="hljs-built_in">shopt</span> -u cdable_vars              
<span class="hljs-built_in">shopt</span> -u cdspell                  
<span class="hljs-built_in">shopt</span> -u checkhash                
<span class="hljs-built_in">shopt</span> -u checkjobs                
<span class="hljs-built_in">shopt</span> -s checkwinsize             
[...]
</code></pre>
<p>Create some variables to add color to the Bash prompt like this:</p>
<pre><code class="lang-bash">blk=<span class="hljs-string">'\[\033[01;30m\]'</span>   <span class="hljs-comment"># Black</span>
red=<span class="hljs-string">'\[\033[01;31m\]'</span>   <span class="hljs-comment"># Red</span>
grn=<span class="hljs-string">'\[\033[01;32m\]'</span>   <span class="hljs-comment"># Green</span>
ylw=<span class="hljs-string">'\[\033[01;33m\]'</span>   <span class="hljs-comment"># Yellow</span>
blu=<span class="hljs-string">'\[\033[01;34m\]'</span>   <span class="hljs-comment"># Blue</span>
pur=<span class="hljs-string">'\[\033[01;35m\]'</span>   <span class="hljs-comment"># Purple</span>
cyn=<span class="hljs-string">'\[\033[01;36m\]'</span>   <span class="hljs-comment"># Cyan</span>
wht=<span class="hljs-string">'\[\033[01;37m\]'</span>   <span class="hljs-comment"># White</span>
clr=<span class="hljs-string">'\[\033[00m\]'</span>      <span class="hljs-comment"># Reset</span>
</code></pre>
<p>This is for the Vim lovers. This will allow you to use vim commands on the command line. This is always the first line I add to my .bashrc.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">set</span> -o vi
</code></pre>
<h2 id="heading-how-to-create-aliases-in-bashrc">How to Create Aliases in .bashrc</h2>
<p>You can use aliases for commands you run a lot. Creating aliases will allow you to type faster, saving time and increasing productivity. </p>
<p>The syntax for creating an alias is <code>alias &lt;my_alias&gt;='longer command'</code>. To find out which commands would make good aliases, run this command to see a list of the top 10 commands you run most.</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">history</span> | awk <span class="hljs-string">'{cmd[$2]++} END {for(elem in cmd) {print cmd[elem] " " elem}}'</span> | sort -n -r | head -10
</code></pre>
<pre><code># Output

<span class="hljs-number">171</span> git
<span class="hljs-number">108</span> cd
<span class="hljs-number">62</span> vim
<span class="hljs-number">51</span> python3
<span class="hljs-number">38</span> history
<span class="hljs-number">32</span> exit
<span class="hljs-number">30</span> clear
<span class="hljs-number">28</span> tmux
<span class="hljs-number">28</span> tree
<span class="hljs-number">27</span> ls
</code></pre><p>Since I use Git a lot, that would be a great command to create an alias for.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># View Git status.</span>
<span class="hljs-built_in">alias</span> gs=<span class="hljs-string">'git status'</span>

<span class="hljs-comment"># Add a file to Git.</span>
<span class="hljs-built_in">alias</span> ga=<span class="hljs-string">'git add'</span>

<span class="hljs-comment"># Add all files to Git.</span>
<span class="hljs-built_in">alias</span> gaa=<span class="hljs-string">'git add --all'</span>

<span class="hljs-comment"># Commit changes to the code.</span>
<span class="hljs-built_in">alias</span> gc=<span class="hljs-string">'git commit'</span>

<span class="hljs-comment"># View the Git log.</span>
<span class="hljs-built_in">alias</span> gl=<span class="hljs-string">'git log --oneline'</span>

<span class="hljs-comment"># Create a new Git branch and move to the new branch at the same time. </span>
<span class="hljs-built_in">alias</span> gb=<span class="hljs-string">'git checkout -b'</span>

<span class="hljs-comment"># View the difference.</span>
<span class="hljs-built_in">alias</span> gd=<span class="hljs-string">'git diff'</span>
</code></pre>
<p>Here are some other useful aliases:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Move to the parent folder.</span>
<span class="hljs-built_in">alias</span> ..=<span class="hljs-string">'cd ..;pwd'</span>

<span class="hljs-comment"># Move up two parent folders.</span>
<span class="hljs-built_in">alias</span> ...=<span class="hljs-string">'cd ../..;pwd'</span>

<span class="hljs-comment"># Move up three parent folders.</span>
<span class="hljs-built_in">alias</span> ....=<span class="hljs-string">'cd ../../..;pwd'</span>
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Press c to clear the terminal screen.</span>
<span class="hljs-built_in">alias</span> c=<span class="hljs-string">'clear'</span>

<span class="hljs-comment"># Press h to view the bash history.</span>
<span class="hljs-built_in">alias</span> h=<span class="hljs-string">'history'</span>

<span class="hljs-comment"># Display the directory structure better.</span>
<span class="hljs-built_in">alias</span> tree=<span class="hljs-string">'tree --dirsfirst -F'</span>

<span class="hljs-comment"># Make a directory and all parent directories with verbosity.</span>
<span class="hljs-built_in">alias</span> mkdir=<span class="hljs-string">'mkdir -p -v'</span>
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># View the calender by typing the first three letters of the month.</span>

<span class="hljs-built_in">alias</span> jan=<span class="hljs-string">'cal -m 01'</span>
<span class="hljs-built_in">alias</span> feb=<span class="hljs-string">'cal -m 02'</span>
<span class="hljs-built_in">alias</span> mar=<span class="hljs-string">'cal -m 03'</span>
<span class="hljs-built_in">alias</span> apr=<span class="hljs-string">'cal -m 04'</span>
<span class="hljs-built_in">alias</span> may=<span class="hljs-string">'cal -m 05'</span>
<span class="hljs-built_in">alias</span> jun=<span class="hljs-string">'cal -m 06'</span>
<span class="hljs-built_in">alias</span> jul=<span class="hljs-string">'cal -m 07'</span>
<span class="hljs-built_in">alias</span> aug=<span class="hljs-string">'cal -m 08'</span>
<span class="hljs-built_in">alias</span> sep=<span class="hljs-string">'cal -m 09'</span>
<span class="hljs-built_in">alias</span> oct=<span class="hljs-string">'cal -m 10'</span>
<span class="hljs-built_in">alias</span> nov=<span class="hljs-string">'cal -m 11'</span>
<span class="hljs-built_in">alias</span> dec=<span class="hljs-string">'cal -m 12'</span>
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Output</span>

$ mar

     March 2021      
Su Mo Tu We Th Fr Sa 
    1  2  3  4  5  6 
 7  8  9 10 11 12 13 
14 15 16 17 18 19 20 
21 22 23 24 25 26 27 
28 29 30 31
</code></pre>
<h2 id="heading-how-to-use-functions-in-bashrc">How to Use Functions in .bashrc</h2>
<p>Functions are great for more complicated code when an alias won't work.</p>
<p>Here's the basic function syntax:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">funct_name</span></span>() {
    <span class="hljs-comment"># code;</span>
}
</code></pre>
<p>This is how you can find the largest files in a directory:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">find_largest_files</span></span>() {
    du -h -x -s -- * | sort -r -h | head -20;
}
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Output</span>

Downloads $ find_largest_files

709M    systemrescue-8.00-amd64.iso
337M    debian-10.8.0-amd64-netinst.iso
9.1M    weather-icons-master.zip
6.3M    Hack-font.zip
3.9M    city.list.json.gz
2.8M    dvdrental.tar
708K    IMG_2600.JPG
100K    sql_cheat_sheet_pgsql.pdf
4.0K    repeating-a-string.txt
4.0K    heart.svg
4.0K    Fedora-Workstation-33-1.2-x86_64-CHECKSUM
[...]
</code></pre>
<p>You can also add colors to the Bash prompt and display the current Git branch like this:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Display the current Git branch in the Bash prompt.</span>

<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">git_branch</span></span>() {
    <span class="hljs-keyword">if</span> [ -d .git ] ; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">printf</span> <span class="hljs-string">"%s"</span> <span class="hljs-string">"(<span class="hljs-subst">$(git branch 2&gt; /dev/null | awk '/\*/{print $2}')</span>)"</span>;
    <span class="hljs-keyword">fi</span>
}

<span class="hljs-comment"># Set the prompt.</span>

<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">bash_prompt</span></span>(){
    PS1=<span class="hljs-string">'${debian_chroot:+($debian_chroot)}'</span><span class="hljs-variable">${blu}</span><span class="hljs-string">'$(git_branch)'</span><span class="hljs-variable">${pur}</span><span class="hljs-string">' \W'</span><span class="hljs-variable">${grn}</span><span class="hljs-string">' \$ '</span><span class="hljs-variable">${clr}</span>
}

bash_prompt
</code></pre>
<p><img src="https://i.postimg.cc/mgg56Zjp/bash-prompt.png" alt="bash-prompt.png" width="740" height="126" loading="lazy">
<em>Custom Bash prompt</em></p>
<p>Grep (search) through your history for previous run commands:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">hg</span></span>() {
    <span class="hljs-built_in">history</span> | grep <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span>;
}
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Output</span>

$ hg vim

305  2021-03-02 16:47:33 vim .bashrc
307  2021-03-02 17:17:09 vim .tmux.conf
</code></pre>
<p>This is how you start a new project with Git:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">git_init</span></span>() {
    <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">printf</span> <span class="hljs-string">"%s\n"</span> <span class="hljs-string">"Please provide a directory name."</span>;
    <span class="hljs-keyword">else</span>
        mkdir <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span>;
        <span class="hljs-built_in">builtin</span> <span class="hljs-built_in">cd</span> <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span>;
        <span class="hljs-built_in">pwd</span>;
        git init;
        touch readme.md .gitignore LICENSE;
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"# <span class="hljs-subst">$(basename $PWD)</span>"</span> &gt;&gt; readme.md
    <span class="hljs-keyword">fi</span>
}
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Output</span>

$ git_init my_project

/home/brandon/my_project
Initialized empty Git repository <span class="hljs-keyword">in</span> /home/brandon/my_project/.git/
</code></pre>
<p>You can also get the weather report on the command line. This requires the package <strong>curl</strong>, <strong>jq</strong>, and an <a target="_blank" href="https://openweathermap.org/api"><strong>API key</strong></a> from <a target="_blank" href="https://openweathermap.org/">Openweathermap.</a> Read the <a target="_blank" href="https://openweathermap.org/api">Openweathermap API documentation</a> in order to configure the URL correctly to get the weather in your location.</p>
<p>Install curl and jq with these commands:</p>
<pre><code class="lang-bash">$ sudo apt install curl jq

<span class="hljs-comment"># OR</span>

$ sudo dnf install curl jq
</code></pre>
<pre><code class="lang-bash"><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">weather_report</span></span>() {

    <span class="hljs-built_in">local</span> response=$(curl --silent <span class="hljs-string">'https://api.openweathermap.org/data/2.5/weather?id=5128581&amp;units=imperial&amp;appid=&lt;YOUR_API_KEY&gt;'</span>) 

    <span class="hljs-built_in">local</span> status=$(<span class="hljs-built_in">echo</span> <span class="hljs-variable">$response</span> | jq -r <span class="hljs-string">'.cod'</span>)

    <span class="hljs-comment"># Check for the 200 response indicating a successful API query.</span>
    <span class="hljs-keyword">case</span> <span class="hljs-variable">$status</span> <span class="hljs-keyword">in</span>

        200) <span class="hljs-built_in">printf</span> <span class="hljs-string">"Location: %s %s\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.name')</span> <span class="hljs-subst">$(echo $response | jq '.sys.country')</span>"</span>  
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Forecast: %s\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.weather[].description')</span>"</span> 
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Temperature: %.1f°F\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.main.temp')</span>"</span> 
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Temp Min: %.1f°F\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.main.temp_min')</span>"</span> 
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Temp Max: %.1f°F\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.main.temp_max')</span>"</span> 
            ;;
        401) <span class="hljs-built_in">echo</span> <span class="hljs-string">"401 error"</span>
            ;;
        *) <span class="hljs-built_in">echo</span> <span class="hljs-string">"error"</span>
            ;;

    <span class="hljs-keyword">esac</span>

}
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># Output</span>

$ weather_report

Location: <span class="hljs-string">"New York"</span> <span class="hljs-string">"US"</span>
Forecast: <span class="hljs-string">"clear sky"</span>
Temperature: 58.0°F
Temp Min: 56.0°F
Temp Max: 60.8°F
</code></pre>
<h2 id="heading-how-to-print-system-information-in-bashrc">How to Print System Information in .bashrc</h2>
<p>You can display useful system information when you open the terminal like this:</p>
<pre><code class="lang-bash">clear

<span class="hljs-built_in">printf</span> <span class="hljs-string">"\n"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"IP ADDR: <span class="hljs-subst">$(curl ifconfig.me)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"USER: <span class="hljs-subst">$(echo $USER)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"DATE: <span class="hljs-subst">$(date)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"UPTIME: <span class="hljs-subst">$(uptime -p)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"HOSTNAME: <span class="hljs-subst">$(hostname -f)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"CPU: <span class="hljs-subst">$(awk -F: '/model name/{print $2}' | head -1)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"KERNEL: <span class="hljs-subst">$(uname -rms)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"PACKAGES: <span class="hljs-subst">$(dpkg --get-selections | wc -l)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"RESOLUTION: <span class="hljs-subst">$(xrandr | awk '/\*/{printf $1<span class="hljs-string">" "</span>}')</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"MEMORY: <span class="hljs-subst">$(free -m -h | awk '/Mem/{print $3<span class="hljs-string">"/"</span>$2}')</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"\n"</span>
</code></pre>
<p>Output:</p>
<p><img src="https://i.postimg.cc/8k6pNN39/Screenshot-2021-03-15-23-39-29.png" alt="Screenshot-2021-03-15-23-39-29.png" width="740" height="426" loading="lazy"></p>
<p>Source the .bashrc file to make the changes take effect:</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">source</span> ~/.bashrc
</code></pre>
<p>Here are all these custom .bashrc settings together. On a new system I paste any customization below the default code in the .bashrc file.</p>
<pre><code class="lang-bash"><span class="hljs-comment">######################################################################</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#           ██████╗  █████╗ ███████╗██╗  ██╗██████╗  ██████╗</span>
<span class="hljs-comment">#           ██╔══██╗██╔══██╗██╔════╝██║  ██║██╔══██╗██╔════╝</span>
<span class="hljs-comment">#           ██████╔╝███████║███████╗███████║██████╔╝██║     </span>
<span class="hljs-comment">#           ██╔══██╗██╔══██║╚════██║██╔══██║██╔══██╗██║     </span>
<span class="hljs-comment">#           ██████╔╝██║  ██║███████║██║  ██║██║  ██║╚██████╗</span>
<span class="hljs-comment">#           ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">######################################################################</span>

<span class="hljs-built_in">set</span> -o vi

HISTTIMEFORMAT=<span class="hljs-string">"%F %T "</span>

HISTCONTROL=ignoredups

HISTSIZE=2000

HISTFILESIZE=2000

<span class="hljs-built_in">shopt</span> -s histappend

blk=<span class="hljs-string">'\[\033[01;30m\]'</span>   <span class="hljs-comment"># Black</span>
red=<span class="hljs-string">'\[\033[01;31m\]'</span>   <span class="hljs-comment"># Red</span>
grn=<span class="hljs-string">'\[\033[01;32m\]'</span>   <span class="hljs-comment"># Green</span>
ylw=<span class="hljs-string">'\[\033[01;33m\]'</span>   <span class="hljs-comment"># Yellow</span>
blu=<span class="hljs-string">'\[\033[01;34m\]'</span>   <span class="hljs-comment"># Blue</span>
pur=<span class="hljs-string">'\[\033[01;35m\]'</span>   <span class="hljs-comment"># Purple</span>
cyn=<span class="hljs-string">'\[\033[01;36m\]'</span>   <span class="hljs-comment"># Cyan</span>
wht=<span class="hljs-string">'\[\033[01;37m\]'</span>   <span class="hljs-comment"># White</span>
clr=<span class="hljs-string">'\[\033[00m\]'</span>      <span class="hljs-comment"># Reset</span>

<span class="hljs-built_in">alias</span> gs=<span class="hljs-string">'git status'</span>

<span class="hljs-built_in">alias</span> ga=<span class="hljs-string">'git add'</span>

<span class="hljs-built_in">alias</span> gaa=<span class="hljs-string">'git add --all'</span>

<span class="hljs-built_in">alias</span> gc=<span class="hljs-string">'git commit'</span>

<span class="hljs-built_in">alias</span> gl=<span class="hljs-string">'git log --oneline'</span>

<span class="hljs-built_in">alias</span> gb=<span class="hljs-string">'git checkout -b'</span>

<span class="hljs-built_in">alias</span> gd=<span class="hljs-string">'git diff'</span>

<span class="hljs-built_in">alias</span> ..=<span class="hljs-string">'cd ..;pwd'</span>

<span class="hljs-built_in">alias</span> ...=<span class="hljs-string">'cd ../..;pwd'</span>

<span class="hljs-built_in">alias</span> ....=<span class="hljs-string">'cd ../../..;pwd'</span>

<span class="hljs-built_in">alias</span> c=<span class="hljs-string">'clear'</span>

<span class="hljs-built_in">alias</span> h=<span class="hljs-string">'history'</span>

<span class="hljs-built_in">alias</span> tree=<span class="hljs-string">'tree --dirsfirst -F'</span>

<span class="hljs-built_in">alias</span> mkdir=<span class="hljs-string">'mkdir -p -v'</span>

<span class="hljs-built_in">alias</span> jan=<span class="hljs-string">'cal -m 01'</span>
<span class="hljs-built_in">alias</span> feb=<span class="hljs-string">'cal -m 02'</span>
<span class="hljs-built_in">alias</span> mar=<span class="hljs-string">'cal -m 03'</span>
<span class="hljs-built_in">alias</span> apr=<span class="hljs-string">'cal -m 04'</span>
<span class="hljs-built_in">alias</span> may=<span class="hljs-string">'cal -m 05'</span>
<span class="hljs-built_in">alias</span> jun=<span class="hljs-string">'cal -m 06'</span>
<span class="hljs-built_in">alias</span> jul=<span class="hljs-string">'cal -m 07'</span>
<span class="hljs-built_in">alias</span> aug=<span class="hljs-string">'cal -m 08'</span>
<span class="hljs-built_in">alias</span> sep=<span class="hljs-string">'cal -m 09'</span>
<span class="hljs-built_in">alias</span> oct=<span class="hljs-string">'cal -m 10'</span>
<span class="hljs-built_in">alias</span> nov=<span class="hljs-string">'cal -m 11'</span>
<span class="hljs-built_in">alias</span> dec=<span class="hljs-string">'cal -m 12'</span>

<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">hg</span></span>() {
    <span class="hljs-built_in">history</span> | grep <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span>;
}

<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">find_largest_files</span></span>() {
    du -h -x -s -- * | sort -r -h | head -20;
}

<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">git_branch</span></span>() {
    <span class="hljs-keyword">if</span> [ -d .git ] ; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">printf</span> <span class="hljs-string">"%s"</span> <span class="hljs-string">"(<span class="hljs-subst">$(git branch 2&gt; /dev/null | awk '/\*/{print $2}')</span>)"</span>;
    <span class="hljs-keyword">fi</span>
}

<span class="hljs-comment"># Set the prompt.</span>
<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">bash_prompt</span></span>(){
    PS1=<span class="hljs-string">'${debian_chroot:+($debian_chroot)}'</span><span class="hljs-variable">${blu}</span><span class="hljs-string">'$(git_branch)'</span><span class="hljs-variable">${pur}</span><span class="hljs-string">' \W'</span><span class="hljs-variable">${grn}</span><span class="hljs-string">' \$ '</span><span class="hljs-variable">${clr}</span>
}

bash_prompt

<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">git_init</span></span>() {
    <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">printf</span> <span class="hljs-string">"%s\n"</span> <span class="hljs-string">"Please provide a directory name."</span>;
    <span class="hljs-keyword">else</span>
        mkdir <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span>;
        <span class="hljs-built_in">builtin</span> <span class="hljs-built_in">cd</span> <span class="hljs-string">"<span class="hljs-variable">$1</span>"</span>;
        <span class="hljs-built_in">pwd</span>;
        git init;
        touch readme.md .gitignore LICENSE;
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"# <span class="hljs-subst">$(basename $PWD)</span>"</span> &gt;&gt; readme.md
    <span class="hljs-keyword">fi</span>
}

<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">weather_report</span></span>() {

    <span class="hljs-built_in">local</span> response=$(curl --silent <span class="hljs-string">'https://api.openweathermap.org/data/2.5/weather?id=5128581&amp;units=imperial&amp;appid=&lt;YOUR_API_KEY&gt;'</span>) 

    <span class="hljs-built_in">local</span> status=$(<span class="hljs-built_in">echo</span> <span class="hljs-variable">$response</span> | jq -r <span class="hljs-string">'.cod'</span>)

    <span class="hljs-keyword">case</span> <span class="hljs-variable">$status</span> <span class="hljs-keyword">in</span>

        200) <span class="hljs-built_in">printf</span> <span class="hljs-string">"Location: %s %s\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.name')</span> <span class="hljs-subst">$(echo $response | jq '.sys.country')</span>"</span>  
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Forecast: %s\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.weather[].description')</span>"</span> 
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Temperature: %.1f°F\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.main.temp')</span>"</span> 
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Temp Min: %.1f°F\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.main.temp_min')</span>"</span> 
             <span class="hljs-built_in">printf</span> <span class="hljs-string">"Temp Max: %.1f°F\n"</span> <span class="hljs-string">"<span class="hljs-subst">$(echo $response | jq '.main.temp_max')</span>"</span> 
            ;;
        401) <span class="hljs-built_in">echo</span> <span class="hljs-string">"401 error"</span>
            ;;
        *) <span class="hljs-built_in">echo</span> <span class="hljs-string">"error"</span>
            ;;

    <span class="hljs-keyword">esac</span>

}

clear

<span class="hljs-built_in">printf</span> <span class="hljs-string">"\n"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"IP ADDR: <span class="hljs-subst">$(curl ifconfig.me)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"USER: <span class="hljs-subst">$(echo $USER)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"DATE: <span class="hljs-subst">$(date)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"UPTIME: <span class="hljs-subst">$(uptime -p)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"HOSTNAME: <span class="hljs-subst">$(hostname -f)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"CPU: <span class="hljs-subst">$(awk -F: '/model name/{print $2}' | head -1)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"KERNEL: <span class="hljs-subst">$(uname -rms)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"PACKAGES: <span class="hljs-subst">$(dpkg --get-selections | wc -l)</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"RESOLUTION: <span class="hljs-subst">$(xrandr | awk '/\*/{printf $1<span class="hljs-string">" "</span>}')</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"   %s\n"</span> <span class="hljs-string">"MEMORY: <span class="hljs-subst">$(free -m -h | awk '/Mem/{print $3<span class="hljs-string">"/"</span>$2}')</span>"</span>
<span class="hljs-built_in">printf</span> <span class="hljs-string">"\n"</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article you learned how to configure various .bashrc options, aliases, functions, and more to greatly improve your workflow and increase your productivity.</p>
<p>Follow me on <a target="_blank" href="https://github.com/brandon-wallace">Github</a> | <a target="_blank" href="https://dev.to/brandonwallace">Dev.to</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Shell scripting ]]>
                </title>
                <description>
                    <![CDATA[ In the command line, a shell script is an executable file that contains a set of instructions that the shell will execute. Its main purpose is to reduce a set of instructions (or commands) in just one file. Also it can handle some logic because it’s ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/shell-scripting/</link>
                <guid isPermaLink="false">66c35eb7e4cb1ff6521c8248</guid>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 07 Jan 2020 18:16:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9e14740569d1a4ca3b3b.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In the command line, a shell script is an executable file that contains a set of instructions that the shell will execute. Its main purpose is to reduce a set of instructions (or commands) in just one file. Also it can handle some logic because it’s a programming language.</p>
<h2 id="heading-how-to-create-it"><strong>How to create it</strong></h2>
<p>Create the file:</p>
<pre><code class="lang-bash">$ touch myscript.sh
</code></pre>
<p>Add a <a target="_blank" href="https://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a> at the start of the file. The Shebang line is responsible for letting the command interpreter know which interpreter the shell script will be run with:</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">echo</span> <span class="hljs-string">"#!/bin/bash"</span> &gt; myscript.sh
<span class="hljs-comment"># or</span>
$ your-desired-editor myscript.sh
<span class="hljs-comment"># write at the first line #!/bin/bash</span>
</code></pre>
<p>Add some commands:</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">echo</span> <span class="hljs-string">"echo Hello World!"</span> &gt;&gt; myscript.sh
</code></pre>
<p>Give the file <em>execution</em> mode:</p>
<pre><code class="lang-bash">$ chmod +x myscript.sh
</code></pre>
<p>Execute it!</p>
<pre><code class="lang-bash">$ ./myscript.sh
Hello World!
</code></pre>
<p>More info about shell-scripting can be found <a target="_blank" href="https://www.shellscript.sh/">here</a></p>
<h2 id="heading-more-info-on-shell-scripting-and-linux">More info on shell scripting and Linux:</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/a-beginners-guide-to-surviving-in-the-linux-shell-cda0f5a0698c/">A beginner's guide to surviving in the Linux shell</a></li>
<li><a target="_blank" href="https://guide.freecodecamp.org/linux/basic-linux-commands">Basic Linux commands to know</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/functional-and-flexible-shell-scripting-tricks-a2d693be2dd4/">Shell scripting tricks</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Bash and shell expansions: lazy list-making ]]>
                </title>
                <description>
                    <![CDATA[ It’s that time of year again! When stores start putting up colourful sparkly lit-up plastic bits, we all begin to feel a little festive, and by festive I mean let’s go shopping. Specifically, holiday gift shopping! (Gifts for yourself are still gifts... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/bash-shell-expansions/</link>
                <guid isPermaLink="false">66bd8f15c89bd16700302de7</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Thu, 21 Nov 2019 15:14:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/cover-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>It’s that time of year again! When stores start putting up colourful sparkly lit-up plastic bits, we all begin to feel a little festive, and by festive I mean let’s go shopping. Specifically, holiday gift shopping! (Gifts for yourself are still gifts, technically.)</p>
<p>Just so this doesn’t all go completely madcap, you ought to make some gift lists. Bash can help.</p>
<h2 id="heading-brace-expansion">Brace expansion</h2>
<p>These are not braces: <code>()</code></p>
<p>Neither are these: <code>[]</code></p>
<p><em>These</em> are braces: <code>{}</code></p>
<p>Braces  tell Bash to do something with the arbitrary string or strings it finds  between them. Multiple strings are comma-separated: <code>{a,b,c}</code>. You can also add an optional preamble and postscript to be attached to each expanded result. Mostly, this can save some typing, such as with common file paths and extensions.</p>
<p>Let’s make some lists for each person we want to give stuff to. The following commands are equivalent:</p>
<pre><code class="lang-sh">touch /home/me/gift-lists/Amy.txt /home/me/gift-lists/Bryan.txt /home/me/gift-lists/Charlie.txt
</code></pre>
<pre><code class="lang-sh">touch /home/me/gift-lists/{Amy,Bryan,Charlie}.txt
</code></pre>
<pre><code class="lang-sh">tree gift-lists

/home/me/gift-lists
├── Amy.txt
├── Bryan.txt
└── Charlie.txt
</code></pre>
<p>Oh darn, “Bryan” spells his name with an “i.” I can fix that.</p>
<pre><code class="lang-sh">mv /home/me/gift-lists/{Bryan,Brian}.txt

renamed <span class="hljs-string">'/home/me/gift-lists/Bryan.txt'</span> -&gt; <span class="hljs-string">'/home/me/gift-lists/Brian.txt'</span>
</code></pre>
<h2 id="heading-shell-parameter-expansions">Shell parameter expansions</h2>
<p><a target="_blank" href="https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html">Shell parameter expansion</a> allows us to make all sorts of changes to parameters enclosed in braces, like manipulate and substitute text.</p>
<p>There are a few stocking stuffers that all our giftees deserve. Let’s make that a variable:</p>
<pre><code class="lang-sh">STUFF=$<span class="hljs-string">'socks\nlump of coal\nwhite chocolate'</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$STUFF</span>"</span>
socks
lump of coal
white chocolate
</code></pre>
<p>Now to add these items to each of our lists with some help from <a target="_blank" href="https://en.wikipedia.org/wiki/Tee_(command)">the <code>tee</code> command</a> to get <code>echo</code> and expansions to play nice.</p>
<pre><code class="lang-sh"><span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$STUFF</span>"</span> | tee {Amy,Brian,Charlie}.txt

cat {Amy,Brian,Charlie}.txt

socks
lump of coal
white chocolate
socks
lump of coal
white chocolate
socks
lump of coal
white chocolate
</code></pre>
<h3 id="heading-pattern-match-substitution">Pattern match substitution</h3>
<p>On  second thought, maybe the lump of coal isn’t such a nice gift. You can  replace it with something better using a pattern match substitution in  the form of <code>${parameter/pattern/string}</code>:</p>
<pre><code class="lang-sh"><span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">${STUFF/lump of coal/candy cane}</span>"</span> | tee {Amy,Brian,Charlie}.txt

cat {Amy,Brian,Charlie}.txt

socks
candy cane
white chocolate
socks
candy cane
white chocolate
socks
candy cane
white chocolate
</code></pre>
<p>This replaces the first instance of “lump of coal” with “candy cane.” To replace all instances (if there were multiple), use <code>${parameter//pattern/string}</code>. This doesn’t change our <code>$STUFF</code> variable, so we can still reuse the original list for someone naughty later.</p>
<h3 id="heading-substrings">Substrings</h3>
<p>While  we’re improving things, our giftees may not all like white chocolate.  We’d better add some regular chocolate to our lists just in case. Since  I’m super lazy, I’m just going to hit the up arrow and modify a previous  Bash command. Luckily, the last word in the <code>$STUFF</code> variable is “chocolate,” which is nine characters long, so I’ll tell Bash to keep just that part using <code>${parameter:offset}</code>. I’ll use <code>tee</code>’s <code>-a</code> flag to <code>a</code>ppend to my existing lists:</p>
<pre><code class="lang-sh"><span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">${STUFF: -9}</span>"</span> | tee -a {Amy,Brian,Charlie}.txt

cat {Amy,Brian,Charlie}.txt

socks
candy cane
white chocolate
chocolate
socks
candy cane
white chocolate
chocolate
socks
candy cane
white chocolate
chocolate
</code></pre>
<p>You can also:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Do this</td><td>With this</td></tr>
</thead>
<tbody>
<tr>
<td>Get substring from <em>n</em> characters onwards</td><td><code>${parameter:n}</code></td></tr>
<tr>
<td>Get substring for <em>x</em> characters starting at <em>n</em></td><td><code>${parameter:n:x}</code></td></tr>
</tbody>
</table>
</div><p>There! Now our base lists are finished. Let’s have some eggnog.</p>
<h3 id="heading-testing-variables">Testing variables</h3>
<p>You  know, it may be the eggnog, but I think I started a list for Amy  yesterday and stored it in a variable that I might have called <code>amy</code>. Let’s see if I did. I’ll use the <code>${parameter:?word}</code> expansion. It’ll write <code>word</code> to standard error and exit if there’s no <code>amy</code> parameter.</p>
<pre><code class="lang-sh"><span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">${amy:?no such}</span>"</span>

bash: amy: no such
</code></pre>
<p>I guess not. Maybe it was Brian instead?</p>
<pre><code class="lang-sh"><span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">${brian:?no such}</span>"</span>

Lederhosen
</code></pre>
<p>You can also:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Do this</td><td>With this</td></tr>
</thead>
<tbody>
<tr>
<td>Substitute <code>word</code> if <code>parameter</code> is unset or null</td><td><code>${parameter:-word}</code></td></tr>
<tr>
<td>Substitute <code>word</code> if <code>parameter</code> is not unset or null</td><td><code>${parameter:+word}</code></td></tr>
<tr>
<td>Assign <code>word</code> to <code>parameter</code> if <code>parameter</code> is unset or null</td><td><code>${parameter:=word}</code></td></tr>
</tbody>
</table>
</div><h3 id="heading-changing-case">Changing case</h3>
<p>That’s  right! Brian said he wanted some lederhosen and so I made myself a  note. This is pretty important, so I’ll add it to Brian’s list in  capital letters with the <code>${parameter^^pattern}</code> expansion. The <code>pattern</code> part is optional. We’re only writing to Brian’s list, so I’ll just use <code>&gt;&gt;</code> instead of <code>tee -a</code>.</p>
<pre><code class="lang-sh"><span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">${brian^^}</span>"</span> &gt;&gt; Brian.txt

cat Brian.txt

socks
candy cane
white chocolate
chocolate
LEDERHOSEN
</code></pre>
<p>You can also:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Do this</td><td>With this</td></tr>
</thead>
<tbody>
<tr>
<td>Capitalize the first letter</td><td><code>${parameter^pattern}</code></td></tr>
<tr>
<td>Lowercase the first letter</td><td><code>${parameter,pattern}</code></td></tr>
<tr>
<td>Lowercase all letters</td><td><code>${parameter,,pattern}</code></td></tr>
</tbody>
</table>
</div><h3 id="heading-expanding-arrays">Expanding arrays</h3>
<p>You know what, all this gift-listing business is a lot of work. I’m just going to make <a target="_blank" href="https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Arrays">an array</a> of things I saw at the store:</p>
<pre><code class="lang-sh">gifts=(sweater gameboy wagon pillows chestnuts hairbrush)
</code></pre>
<p>I can use substring expansion in the form of <code>${parameter:offset:length}</code> to make this simple. I’ll add the first two to Amy’s list, the middle two to Brian’s, and the last two to Charlie’s. I’ll use <code>printf</code> to help with newlines.</p>
<pre><code class="lang-sh"><span class="hljs-built_in">printf</span> <span class="hljs-string">'%s\n'</span> <span class="hljs-string">"<span class="hljs-variable">${gifts[@]:0:2}</span>"</span> &gt;&gt; Amy.txt
<span class="hljs-built_in">printf</span> <span class="hljs-string">'%s\n'</span> <span class="hljs-string">"<span class="hljs-variable">${gifts[@]:2:2}</span>"</span> &gt;&gt; Brian.txt
<span class="hljs-built_in">printf</span> <span class="hljs-string">'%s\n'</span> <span class="hljs-string">"<span class="hljs-variable">${gifts[@]: -2}</span>"</span> &gt;&gt; Charlie.txt
</code></pre>
<pre><code class="lang-sh">cat Amy.txt

socks
candy cane
white chocolate
chocolate
sweater
gameboy

cat Brian.txt

socks
candy cane
white chocolate
chocolate
LEDERHOSEN
wagon
pillows

cat Charlie.txt

socks
candy cane
white chocolate
chocolate
chestnuts
hairbrush
</code></pre>
<p>There! Now we’ve got a comprehensive set of super personalized gift lists. Thanks Bash! Too bad it can’t do the shopping for us, too.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to publish GitHub event data with GitHub Actions and Pages ]]>
                </title>
                <description>
                    <![CDATA[ Teams who work on GitHub rely on event data to collaborate.  The data recorded as issues, pull requests, and comments become vital to understanding the project. With the general availability of GitHub Actions, we have a chance to programmatically acc... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/publishing-github-event-data-with-github-actions-and-pages/</link>
                <guid isPermaLink="false">66bd8f70c1ca1df1936e29d9</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub Actions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ github pages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Tue, 05 Nov 2019 14:12:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Teams who work on GitHub rely on event data to collaborate.  The data recorded as issues, pull requests, and comments become vital to understanding the project.</p>
<p>With the general availability of GitHub Actions, we have a chance to programmatically access and preserve GitHub event data in our repository. Making the data part of the repository itself is a way of preserving it outside of GitHub. It also gives us the ability to feature the data on a front-facing website, such as with GitHub Pages.</p>
<p>And, if you’re like me, you can turn <a target="_blank" href="https://github.com/victoriadrake/github-guestbook/issues/1">GitHub issue comments</a> into an <a target="_blank" href="https://victoria.dev/github-guestbook/">awesome 90s guestbook page</a>.</p>
<p>No matter the usage, the principle concepts are the same. We can use Actions to access, preserve, and display GitHub event data - with just one workflow file. To illustrate the process, I’ll take you through the <a target="_blank" href="https://github.com/victoriadrake/github-guestbook/blob/master/.github/workflows/publish-comments.yml">workflow code</a> that makes my guestbook shine on.</p>
<p>For an introductory look at GitHub Actions including how workflows are triggered, see <a target="_blank" href="https://victoria.dev/blog/a-lightweight-tool-agnostic-ci/cd-flow-with-github-actions/">A lightweight, tool-agnostic CI/CD flow with GitHub Actions</a>.</p>
<h2 id="heading-accessing-github-event-data">Accessing GitHub event data</h2>
<p>An Action workflow runs in an environment with some default environment variables. A lot of convenient information is available here, including event data. The most complete way to access the event data is using the <code>$GITHUB_EVENT_PATH</code> variable, the path of the file with the complete JSON event payload.</p>
<p>The expanded path looks like <code>/home/runner/work/_temp/_github_workflow/event.json</code> and its data corresponds to its webhook event. You can find the documentation for webhook event data in GitHub REST API <a target="_blank" href="https://developer.github.com/webhooks/#events">Event Types and Payloads</a>. To make the JSON data available in the workflow environment, you can use a tool like <code>jq</code> to parse the event data and put it in an environment variable.</p>
<p>Below, I grab the comment ID from an <a target="_blank" href="https://developer.github.com/v3/activity/events/types/#issuecommentevent">issue comment event</a>:</p>
<pre><code>ID=<span class="hljs-string">"$(jq '.comment.id' $GITHUB_EVENT_PATH)"</span>
</code></pre><p>Most event data is also available via the <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context"><code>github.event</code> context variable</a> without needing to parse JSON. The fields are accessed using dot notation, as in the example below where I grab the same comment ID:</p>
<pre><code>ID=${{ github.event.comment.id }}
</code></pre><p>For my guestbook, I want to display entries with the user’s handle, and the date and time. I can capture this event data like so:</p>
<pre><code>AUTHOR=${{ github.event.comment.user.login }}
DATE=${{ github.event.comment.created_at }}
</code></pre><p>Shell variables are handy for accessing data, however, they’re ephemeral. The workflow environment is created anew each run, and even shell variables set in one step do not persist to other steps. To persist the captured data, you have two options: use artifacts, or commit it to the repository.</p>
<h2 id="heading-preserving-event-data-using-artifacts">Preserving event data: using artifacts</h2>
<p>Using artifacts, you can persist data between workflow jobs without committing it to your repository. This is handy when, for example, you wish to transform or incorporate the data before putting it somewhere more permanent. It’s necessary to persist data between workflow jobs because:</p>
<blockquote>
<p>Each job in a workflow runs in a fresh instance of the virtual environment. When the job completes, the runner terminates and deletes the instance of the virtual environment. <em>(<a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/persisting-workflow-data-using-artifacts">Persisting workflow data using artifacts</a>)</em></p>
</blockquote>
<p>Two actions assist with using artifacts: <code>upload-artifact</code> and <code>download-artifact</code>. You can use these actions to make files available to other jobs in the same workflow. For a full example, see <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/persisting-workflow-data-using-artifacts#passing-data-between-jobs-in-a-workflow">passing data between jobs in a workflow</a>.</p>
<p>The <code>upload-artifact</code> action’s <code>action.yml</code> contains an <a target="_blank" href="https://github.com/actions/upload-artifact/blob/master/action.yml">explanation</a> of the keywords. The uploaded files are saved in <code>.zip</code> format. Another job in the same workflow run can use the <code>download-artifact</code> action to utilize the data in another step.</p>
<p>You can also manually download the archive on the workflow run page, under the repository’s Actions tab.</p>
<p>Persisting workflow data between jobs does not make any changes to the repository files, as the artifacts generated live only in the workflow environment. </p>
<p>Personally, being comfortable working in a shell  environment, I see a narrow use case for artifacts, though I’d have been remiss not to mention them. Besides passing data between jobs, they could be useful for creating <code>.zip</code> format archives of, say, test output data. In the case of my guestbook example, I simply ran all  the necessary steps in one job, negating any need for passing data  between jobs.</p>
<h2 id="heading-preserving-event-data-pushing-workflow-files-to-the-repository">Preserving event data: pushing workflow files to the repository</h2>
<p>To preserve data captured in the workflow in the repository itself, it is necessary to add and push this data to the Git repository. You can do this in the workflow by creating new files with the data, or by appending data to existing files, using shell commands.</p>
<h3 id="heading-creating-files-in-the-workflow">Creating files in the workflow</h3>
<p>To work with the repository files in the workflow, use the <a target="_blank" href="https://github.com/actions/checkout"><code>checkout</code> action</a> to first get a copy to work with:</p>
<pre><code>- uses: actions/checkout@master
  <span class="hljs-attr">with</span>:
    fetch-depth: <span class="hljs-number">1</span>
</code></pre><p>To add comments to my guestbook, I turn the event data captured in shell variables into proper files, using substitutions in <a target="_blank" href="https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html">shell parameter expansion</a> to sanitize user input and translate newlines to paragraphs. I wrote previously about <a target="_blank" href="https://victoria.dev/blog/sql-injection-and-xss-what-white-hat-hackers-know-about-trusting-user-input/">why user input should be treated carefully</a>.</p>
<pre><code>- name: Turn comment into file
  <span class="hljs-attr">run</span>: |
    ID=${{ github.event.comment.id }}
    AUTHOR=${{ github.event.comment.user.login }}
    DATE=${{ github.event.comment.created_at }}
    COMMENT=$(echo <span class="hljs-string">"${{ github.event.comment.body }}"</span>)
    NO_TAGS=${COMMENT<span class="hljs-comment">//[&lt;&gt;]/\`}</span>
    FOLDER=comments

    printf <span class="hljs-string">'%b\n'</span> <span class="hljs-string">"&lt;div class=\"comment\"&gt;&lt;p&gt;${AUTHOR} says:&lt;/p&gt;&lt;p&gt;${NO_TAGS//$'\n'/\&lt;\/p\&gt;\&lt;p\&gt;}&lt;/p&gt;&lt;p&gt;${DATE}&lt;/p&gt;&lt;/div&gt;\r\n"</span> &gt; ${FOLDER}/${ID}.html
</code></pre><p>By using <code>printf</code> and directing its output with <code>&gt;</code> to a new file, the event data is transformed into an HTML file, named with the comment ID number, that contains the captured event data. Formatted, it looks like:</p>
<pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"comment"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>victoriadrake says:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a comment!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>2019-11-04T00:28:36Z<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
&lt;/div&gt;
</code></pre><p>When working with comments, one effect of naming files using the comment ID is that a new file with the same ID will overwrite the previous. This is handy for a guestbook, as it allows any edits to a comment to replace the original comment file.</p>
<p>If you’re using a static site generator like Hugo, you could build a Markdown format file, stick it in your <code>content/</code> folder, and the regular site build will take care of the rest. </p>
<p>In the case of my simplistic guestbook, I have an extra step to consolidate the  individual comment files into a page. Each time it runs, it overwrites the existing <code>index.html</code> with the <code>header.html</code> portion (<code>&gt;</code>), then finds and appends (<code>&gt;&gt;</code>) all the comment files’ contents in descending order, and lastly appends the <code>footer.html</code> portion to end the page.</p>
<pre><code>- name: Assemble page
  <span class="hljs-attr">run</span>: |
    cat header.html &gt; index.html
    find comments/ -name <span class="hljs-string">"*.html"</span> | sort -r | xargs -I % cat % &gt;&gt; index.html
    cat footer.html &gt;&gt; index.html
</code></pre><h3 id="heading-committing-changes-to-the-repository">Committing changes to the repository</h3>
<p>Since the <code>checkout</code> action is not quite the same as cloning the repository, at time of writing, there are some <a target="_blank" href="https://github.community/t5/GitHub-Actions/Checkout-Action-does-not-create-local-master-and-has-no-options/td-p/31575">issues</a> still to work around. A couple extra steps are necessary to <code>pull</code>, <code>checkout</code>, and successfully <code>push</code> changes back to the <code>master</code> branch, but this is pretty trivially done in the shell.</p>
<p>Below is the step that adds, commits, and pushes changes made by the workflow back to the repository’s <code>master</code> branch.</p>
<pre><code>- name: Push changes to repo
  <span class="hljs-attr">run</span>: |
    REMOTE=https:<span class="hljs-comment">//${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}</span>
    git config user.email <span class="hljs-string">"${{ github.actor }}@users.noreply.github.com"</span>
    git config user.name <span class="hljs-string">"${{ github.actor }}"</span>

    git pull ${REMOTE}
    git checkout master
    git add .
    git status
    git commit -am <span class="hljs-string">"Add new comment"</span>
    git push ${REMOTE} master
</code></pre><p>The remote, in fact, our repository, is specified using the <code>github.repository</code> context variable. For our workflow to be allowed to push to master, we use the <code>secrets.GITHUB_TOKEN</code> variable.</p>
<p>Since the workflow environment is shiny and newborn, we need to configure Git. In the above example, I’ve used the <code>github.actor</code> context variable to input the username of the account initiating the workflow. The email is similarly configured using the <a target="_blank" href="https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address#setting-your-commit-email-address-on-github">default <code>noreply</code> GitHub email address</a>.</p>
<h2 id="heading-displaying-event-data">Displaying event data</h2>
<p><em>Nov 6, 2019 correction: GitHub Actions requires a Personal Access Token to trigger a Pages site build.</em></p>
<p>If you're using GitHub Pages with the default <code>secrets.GITHUB_TOKEN</code> variable and without a site generator, pushing changes to the  repository in the workflow will only update the repository files. The  GitHub Pages build will fail with an error, "Your site is having  problems building: Page build failed."</p>
<p>To enable Actions to trigger a Pages site build, you'll need to create a Personal Access Token. This token can be <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets">stored as a secret in the repository</a> settings and passed into the workflow in place of the default <code>secrets.GITHUB_TOKEN</code> variable. I wrote more about <a target="_blank" href="https://victoria.dev/blog/a-lightweight-tool-agnostic-ci/cd-flow-with-github-actions/#environment-and-variables">Actions environment and variables in this post</a>.</p>
<p>With the use of a Personal Access Token, a push initiated by the  Actions workflow will also update the Pages site. You can see it for  yourself by <a target="_blank" href="https://github.com/victoriadrake/github-guestbook/issues/1">leaving a comment</a> in my <a target="_blank" href="https://victoria.dev/github-guestbook/">guestbook</a>!  The comment creation event triggers the workflow, which then takes  around 30 seconds to a minute to run and update the guestbook page.</p>
<p>Where a site build is necessary for changes to be published, such as  when using Hugo, an Action can do this too. However, in order to avoid  creating unintended loops, <a target="_blank" href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/events-that-trigger-workflows#about-workflow-events">one Action workflow will not trigger another</a>. Instead, it's extremely convenient to handle the process of <a target="_blank" href="https://victoria.dev/blog/a-portable-makefile-for-continuous-delivery-with-hugo-and-github-pages/">building the site with a Makefile</a>,  which any workflow can then run. Simply add running the Makefile as the  final step in your workflow job, with the repository token where  necessary:</p>
<pre><code>- name: Run Makefile
  <span class="hljs-attr">env</span>:
    TOKEN: ${{ secrets.GITHUB_TOKEN }}
  <span class="hljs-attr">run</span>: make all
</code></pre><p>This ensures that the final step of your workflow builds and deploys the updated site.</p>
<h2 id="heading-no-more-event-data-horizon">No more event data horizon</h2>
<p>GitHub Actions provides a neat way to capture and utilize event data so that it’s not only available within GitHub. The possibilities are only as limited as your imagination! Here are a few ideas for things this lets us create:</p>
<ol>
<li>A public-facing issues board, where customers without GitHub accounts can view and give feedback on project issues.</li>
<li>An automatically-updating RSS feed of new issues, comments, or PRs for any repository.</li>
<li>A comments system for static sites, utilizing GitHub issue comments as an input method.</li>
<li>An awesome 90s guestbook page.</li>
</ol>
<p>Did I mention I made a <a target="_blank" href="https://victoria.dev/github-guestbook/">90s guestbook page</a>? My inner-Geocities-nerd is a little excited.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up a Fresh Ubuntu Desktop Using Only Dotfiles and Bash Scripts ]]>
                </title>
                <description>
                    <![CDATA[ One of my most favourite things about open source files on GitHub is the ability to see how others do (what some people might call) mundane things, like set up their .bashrc and other dotfiles. While I’m not as enthusiastic about ricing as I was when... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-a-fresh-ubuntu-desktop-using-only-dotfiles-and-bash-scripts/</link>
                <guid isPermaLink="false">66bd8f512fbe28509b2d6e92</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Scripting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Wed, 21 Aug 2019 13:05:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/08/E62F2B0D-E706-4A55-BAAC-84EF3F59D538.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>One of my most favourite things about open source files on GitHub is the ability to see how others do (what some people might call) mundane things, like set up their <code>.bashrc</code> and other dotfiles. While I’m not as enthusiastic about ricing as I was when I first came to the Linux side, I still get pretty excited when I find a config setting that makes things prettier and faster, and thus, better.</p>
<p>I recently came across a few such things, particularly in <a target="_blank" href="https://github.com/tomnomnom">Tom Hudson’s</a> dotfiles. Tom seems to like to script things, and some of those things include automatically setting up symlinks, and installing Ubuntu repository applications and other programs. This got me thinking. Could I automate the set up of a new machine to replicate my current one?</p>
<p>Being someone generally inclined to take things apart in order to see how they work, I know I’ve messed up my laptop on occasion. (Usually when I’m away from home, and my backup harddrive isn’t.) On those rare but really inconvenient situations when my computer becomes a shell of its former self, (ba-dum-ching) it’d be quite nice to have a fast, simple way of putting Humpty Dumpty back together again, just the way I like.</p>
<p>In contrast to creating a <a target="_blank" href="https://askubuntu.com/questions/19901/how-to-make-a-disk-image-and-restore-from-it-later">disk image and restoring it later</a>, a collection of bash scripts is easier to create, maintain, and move around. They require no special utilities, only an external transportation method. It’s like passing along the recipe, instead of the whole bundt cake. (Mmm, cake.)</p>
<p>Additionally, functionality like this would be super useful when setting up a virtual machine, or VM, or even just a virtual private server, or VPS. (Both of which, now that I write this, would probably make more forgiving targets for my more destructive experimentations… live and learn!)</p>
<p>Well, after some grepping and Googling and digging around, I now have a suite of scripts that can do this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/cover-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>See <a target="_blank" href="https://victoria.dev/verbose/how-to-set-up-a-fresh-ubuntu-desktop-using-only-dotfiles-and-bash-scripts">a video of the setup here</a>.</em></p>
<p>This is the tail end of a test run of the set up scripts on a fresh Ubuntu desktop, loaded off a bootable USB. It had all my programs and settings restored in under three minutes!</p>
<p>This post will cover how to achieve the automatic set up of a computer running Ubuntu Desktop (in my case, Ubuntu LTS 18.04) using bash scripts. The majority of the information covered is applicable to all the Linux desktop flavours, though some syntax may differ. The bash scripts cover three main areas: linking dotfiles, installing software from Ubuntu and elsewhere, and setting up the desktop environment. We’ll cover each of these areas and go over the important bits so that you can begin to craft your own scripts.</p>
<h1 id="heading-dotfiles">Dotfiles</h1>
<p>Dotfiles are what most Linux enthusiasts call configuration files. They typically live in the user’s home directory (denoted in bash scripts with the <a target="_blank" href="https://www.tldp.org/LDP/abs/html/internal.html#BUILTINREF">builtin</a> variable <code>$HOME</code>) and control the appearance and behaviour of all kinds of programs. The file names begin with <code>.</code>, which denotes hidden files in Linux (hence “dot” files). Here are some common dotfiles and ways in which they’re useful.</p>
<h2 id="heading-bashrc"><code>.bashrc</code></h2>
<p>The <code>.bashrc</code> file is a list of commands executed at startup by interactive, non-login shells. <a target="_blank" href="https://www.tldp.org/LDP/abs/html/intandnonint.html">Interactive vs non-interactive shells</a> can be a little confusing, but aren’t necessary for us to worry about here. For our purposes, any time you open a new terminal, see a prompt, and can type commands into it, your <code>.bashrc</code> was executed.</p>
<p>Lines in this file can help improve your workflow by creating aliases that reduce keystrokes, or by displaying a helpful prompt with useful information. It can even run user-created programs, like <a target="_blank" href="https://github.com/victoriadrake/eddie-terminal">Eddie</a>. For more ideas, you can have a look at <a target="_blank" href="https://github.com/victoriadrake/dotfiles/blob/ubuntu-19.10/.bashrc">my <code>.bashrc</code> file on GitHub</a>.</p>
<h2 id="heading-vimrc"><code>.vimrc</code></h2>
<p>The <code>.vimrc</code> dotfile configures the champion of all text editors, <a target="_blank" href="https://www.vim.org/about.php">Vim</a>. (If you haven’t yet wielded the powers of the keyboard shortcuts, I highly recommend <a target="_blank" href="https://vim-adventures.com/">a fun game to learn Vim with</a>.)</p>
<p>In <code>.vimrc</code>, we can set editor preferences such as display settings, colours, and custom keyboard shortcuts. You can take a look at <a target="_blank" href="https://github.com/victoriadrake/dotfiles/blob/ubuntu-19.10/.vimrc">my <code>.vimrc</code> on GitHub</a>.</p>
<p>Other dotfiles may be useful depending on the programs you use, such as <code>.gitconfig</code> or <code>.tmux.conf</code>. Exploring dotfiles on GitHub is a great way to get a sense of what’s available and useful to you!</p>
<h1 id="heading-linking-dotfiles">Linking dotfiles</h1>
<p>We can use a script to create symbolic links, or <a target="_blank" href="https://en.wikipedia.org/wiki/Symbolic_link#POSIX_and_Unix-like_operating_systems">symlinks</a> for all our dotfiles. This allows us to keep all the files in a central repository, where they can easily be managed, while also providing a sort of placeholder in the spot that our programs expect the configuration file to be found. This is typically, but not always, the user home directory. For example, since I store my dotfiles on GitHub, I keep them in a directory with a path like <code>~/github/dotfiles/</code> while the files themselves are symlinked, resulting in a path like <code>~/.vimrc</code>.</p>
<p>To programmatically check for and handle any existing files and symlinks, then create new ones, we can use <a target="_blank" href="https://github.com/victoriadrake/dotfiles/blob/master/scripts/symlink.sh">this elegant shell script</a>. I compliment it only because I blatantly stole the core of it from <a target="_blank" href="https://github.com/tomnomnom/dotfiles/blob/master/setup.sh">Tom’s setup script</a>, so I can’t take the credit for how lovely it is.</p>
<p>The <code>symlink.sh</code> script works by attempting to create symlinks for each dotfile in our <code>$HOME</code>. It first checks to see if a symlink already exists, or if a regular file or directory with the same name exists. In the former case, the symlink is removed and remade; in the latter, the file or directory is renamed, then the symlink is made.</p>
<h1 id="heading-installing-software">Installing software</h1>
<p>One of the beautiful things about exploring shell scripts is discovering how much can be achieved using only the command line. As someone whose first exposure to computers was through a graphical operating system, I find working in the terminal to be refreshingly fast.</p>
<p>With Ubuntu, most programs we likely require are available through the default Ubuntu software repositories. We typically search for these with the command <code>apt search &lt;program&gt;</code> and install them with <code>sudo apt install &lt;program&gt;</code>. Some software we’d like may not be in the default repositories, or may not be offered there in the most current version. In these cases, we can still install these programs in Ubuntu using a <a target="_blank" href="https://en.wikipedia.org/wiki/Ubuntu#Package_Archives">PPA, or Personal Package Archive</a>. We’ll just have to be careful that the PPAs we choose are from the official sources.</p>
<p>If a program we’d like doesn’t appear in the default repositories or doesn’t seem to have a PPA, we may still be able to install it via command line. A quick search for “installation command line” should get some answers.</p>
<p>Since bash scripts are just a collection of commands that we could run individually in the terminal, creating a script to install all our desired programs is as straightforward as putting all the commands into a script file. I chose to organize my installation scripts between the default repositories, which are installed by <a target="_blank" href="https://github.com/victoriadrake/dotfiles/blob/ubuntu-19.10/scripts/aptinstall.sh">my <code>aptinstall.sh</code> script</a>, and programs that involve external sources, handled with <a target="_blank" href="https://github.com/victoriadrake/dotfiles/blob/ubuntu-19.10/scripts/programs.sh">my <code>programs.sh</code> script.</a></p>
<h1 id="heading-setting-up-the-desktop-environment">Setting up the desktop environment</h1>
<p>On the recent occasions when I’ve gotten a fresh desktop (intentionally or otherwise) I always seem to forget how long it takes to remember, find, and then change all the desktop environment settings. Keyboard shortcuts, workspaces, sound settings, night mode… it adds up!</p>
<p>Thankfully, all these settings have to be stored somewhere in a non-graphical format, which means that if we can discover how that’s done, we can likely find a way to easily manipulate the settings with a bash script. Lo and behold the terminal command, <code>gsettings list-recursively</code>.</p>
<p>There are a heck of a lot of settings for GNOME desktop environment. We can make the list easier to scroll through (if, like me, you’re sometimes the type of person to say “Just let me look at everything and figure out what I want!”) by piping to <code>less</code>: <code>gsettings list-recursively | less</code>. Alternatively, if we have an inkling as to what we might be looking for, we can use <code>grep</code>: <code>gsettings list-recursively | grep 'keyboard'</code>.</p>
<p>We can manipulate our settings with the <code>gsettings set</code> command. It can sometimes be difficult to find the syntax for the setting we want, so when we’re first building our script, I recommend using the GUI to make the changes, then finding the <code>gsettings</code> line we changed and recording its value.</p>
<p>For some inspiration, you can view <a target="_blank" href="https://github.com/victoriadrake/dotfiles/blob/ubuntu-19.10/scripts/desktop.sh">my <code>desktop.sh</code> settings script on GitHub</a>.</p>
<h1 id="heading-putting-it-all-together">Putting it all together</h1>
<p>Having modular scripts (one for symlinks, two for installing programs, another for desktop settings) is useful for both keeping things organized and for being able to run some but not all of the automated set up. For instance, if I were to set up a VPS in which I only use the command line, I wouldn’t need to bother with installing graphical programs or desktop settings.</p>
<p>In cases where I do want to run all the scripts, however, doing so one-by-one is a little tedious. Thankfully, since bash scripts can themselves be run by terminal commands, we can simply write another master script to run them all!</p>
<p>Here’s my master script to handle the set up of a new Ubuntu desktop machine:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

./symlink.sh
./aptinstall.sh
./programs.sh
./desktop.sh

<span class="hljs-comment"># Get all upgrades</span>
sudo apt upgrade -y

<span class="hljs-comment"># See our bash changes</span>
<span class="hljs-built_in">source</span> ~/.bashrc

<span class="hljs-comment"># Fun hello</span>
figlet <span class="hljs-string">"... and we're back!"</span> | lolcat
</code></pre>
<p>I threw in the upgrade line for good measure. It will make sure that the programs installed on our fresh desktop have the latest updates. Now a simple, single bash command will take care of everything!</p>
<p>You may have noticed that, while our desktop now looks and runs familiarly, these scripts don’t cover one very important area: our files. Hopefully, you have a back up method for those that involves some form of reliable external hardware. If not, and if you tend to put your work in external repository hosts like GitHub or GitLab, I do have a way to <a target="_blank" href="https://victoria.dev/verbose/how-to-write-bash-one-liners-for-cloning-and-managing-github-and-gitlab-repositories/">automatically clone and back up your GitHub repositories with bash one-liners</a>.</p>
<p>Relying on external repository hosts doesn’t offer 100% coverage, however. Files that you wouldn’t put in an externally hosted repository (private or otherwise) consequently can’t be pulled. Git ignored objects that can’t be generated from included files, like private keys and secrets, will not be recreated. Those files, however, are likely small enough that you could fit a whole bunch on a couple encrypted USB flash drives (and if you don’t have private key backups, maybe you ought to do that first?).</p>
<p>That said, I hope this post has given you at least some inspiration as to how dotfiles and bash scripts can help to automate setting up a fresh desktop. If you come up with some settings you find useful, please help others discover them by sharing your dotfiles, too!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Functional and flexible shell scripting tricks ]]>
                </title>
                <description>
                    <![CDATA[ By BinHong Lee Shell scripts vs python or Perl It's 2020 now, who writes shell scripts anymore? Am I right? Well, apparently I do. ¯_(ツ)_/¯ There are some good arguments for that here and here which mainly revolve around 2 things: Shell exists in al... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/functional-and-flexible-shell-scripting-tricks-a2d693be2dd4/</link>
                <guid isPermaLink="false">66c34affa1d481faeda49b54</guid>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Scripting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 07 May 2019 16:15:12 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*ZB2nVJjipU4repVb" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By BinHong Lee</p>
<h3 id="heading-shell-scripts-vs-python-or-perl">Shell scripts vs python or Perl</h3>
<p>It's 2020 now, who writes shell scripts anymore? Am I right? Well, apparently I do. ¯_(ツ)_/¯</p>
<p>There are some good arguments for that <a target="_blank" href="https://stackoverflow.com/questions/796319/strengths-of-shell-scripting-compared-to-python#796343">here</a> and <a target="_blank" href="https://www.linuxquestions.org/questions/linux-newbie-8/what-is-the-difference-between-perl-and-shell-scripting-4175486499/">here</a> which mainly revolve around 2 things:</p>
<ol>
<li>Shell exists in all Unix systems and makes use of system default features.</li>
<li>Shell is an “interactive command function” designed to get user inputs during the process of running them.</li>
</ol>
<p>Also, <a target="_blank" href="https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash">here</a>’s an additional relevant reading about the differences between <code>sh</code> and <code>bash</code>.</p>
<h3 id="heading-arguments">Arguments</h3>
<p>In some occasions, you will need to pass an argument (or expect one) into the script like how you might pass a param into a function. In that case, you will use something like <code>$1</code> for the first argument, <code>$2</code> for the second. Here's an example of how it would look like:</p>
<p>In script <code>run_this.sh</code>:</p>
<pre><code>echo <span class="hljs-string">"The input message was $1."</span>
</code></pre><p>Running the command:</p>
<pre><code>./run_this.sh userInputThe input message was userInput.
</code></pre><p>_Note: The params are separated by spaces so if you want to input a string as a param that contains a space, it might need to be something like <code>./run_this.sh "user input"</code> just so <code>"user input"</code> would be counted as <code>$1</code> entirely._</p>
<p>In the occasion where you are not sure how long the user input might be and you want to capture it all, you would use <code>$@</code> instead. In the following example, I took in the entire string and print it out word by word after breaking them into a string array according to the spaces in between.</p>
<p>In script <code>run_this.sh</code>:</p>
<pre><code>userInputs=($@)<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-string">"${userInputs[@]}"</span>;; <span class="hljs-keyword">do</span>  echo <span class="hljs-string">"$i"</span>done
</code></pre><p>Running the command:</p>
<pre><code>./run_this.sh who knows how long <span class="hljs-built_in">this</span> can gowhoknowshowlongthiscango
</code></pre><h3 id="heading-functions">Functions</h3>
<p>If you have done any sort of programming, you should be familiar with the concept of <em>functions</em>. It's basically a set of commands / operations that you will be repeating over and over again. Instead of repeating it multiple times in your code, you can put them into a function. Then just call the function which effectively reduces the lines of code that need to be written.</p>
<p><em>Side note: If you don’t know already, LOC is a horrible metric for any sort of measurement in terms of programming. Don’t take this from me, take this from <a target="_blank" href="https://www.goodreads.com/quotes/536587-measuring-programming-progress-by-lines-of-code-is-like-measuring">Bill Gates</a>:</em></p>
<blockquote>
<p>“Measuring programming progress by lines of code is like measuring aircraft building progress by weight.”</p>
</blockquote>
<p>Here’s how a normal function looks like:</p>
<pre><code># Declaring the functiondoSomething() {
</code></pre><pre><code>}
</code></pre><pre><code># Calling the functiondoSomething
</code></pre><p>Pretty straightforward and easy to understand. Now, here are a few differences between functions in shell scripts and a normal programming language.</p>
<h3 id="heading-parameters">Parameters</h3>
<p>If you were to pass a parameter / use a parameter into a function in Java, you have to declare them in the function declaration. They look something like this.</p>
<pre><code>public <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> main(<span class="hljs-built_in">String</span>[] args) {    doSomething(<span class="hljs-string">"random String"</span>);}
</code></pre><pre><code>private <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> doSomething (<span class="hljs-built_in">String</span> words) {    System.out.println(words);}
</code></pre><p>In the shell, however, they do not require a declaration of types or names at all. Each of them is like a separate script that lives in the script itself. If you were to use a param, just pass it in and call it like how you would do it if you were taking in input for this script at the top level. Something like this:</p>
<pre><code>doSomething() {    echo $<span class="hljs-number">1</span>}
</code></pre><pre><code>doSomething <span class="hljs-string">"random String"</span>
</code></pre><ol>
<li>Similar to above, if you want to take in everything, you will use <code>$@</code> instead of <code>$1</code> since <code>$1</code> would only use the first input (and <code>$2</code> for the second etc.).</li>
<li>Functions need to be declared ahead of where they are being called. (Usually beginning of the file before any main operations.)</li>
</ol>
<h3 id="heading-return">Return</h3>
<p>Let’s say we create a script like below named <code>run_this.sh</code>:</p>
<pre><code>doSomething() {    echo <span class="hljs-string">"magic"</span>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>}
</code></pre><pre><code>output=<span class="hljs-string">`doSomething`</span>echo $output
</code></pre><p>Now let’s run it and see what is being assigned to the <code>output</code> variable.</p>
<pre><code>$ ./run_this.shmagic
</code></pre><p>Note that instead of <code>0</code>, it shows <code>magic</code> instead. This is because when you do <code>output=</code>doSomething<code>`, it assigns the output message to</code>output` instead of the return value since the output message is how you communicate almost anything in the shell script.</p>
<p>So when does it make sense to use the <code>return</code> call? When you are using it as part of an if statement. Something like this:</p>
<p>In script <code>run_this.sh</code>:</p>
<pre><code>doSomething() {    echo <span class="hljs-string">"magic"</span>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>}
</code></pre><pre><code><span class="hljs-keyword">if</span> doSomething; then    echo <span class="hljs-string">"Its true!"</span>fi
</code></pre><p>Running the command:</p>
<pre><code>./run_this.shIts <span class="hljs-literal">true</span>!
</code></pre><p>In this case, <code>return 0</code> means <code>true</code> while <code>return 1</code> meant <code>false</code> in a traditional <code>boolean</code> sense.</p>
<h3 id="heading-multi-line-echo">Multi-line echo</h3>
<p>There are times when you need to print a multi-line message. There are a few ways to go around this. The easiest way is to use <code>echo</code> multiple times like this:</p>
<pre><code>echo <span class="hljs-string">"line1"</span>echo <span class="hljs-string">"line2"</span>echo <span class="hljs-string">"line3"</span>
</code></pre><p>It works but probably not the most elegant way to get around this. Instead, you can use <code>cat &lt;&amp;l</code>t; EOF instead. Something like this:</p>
<pre><code>cat &lt;&lt; EOFline1line2line3EOF
</code></pre><p>Note that there should not be anything (including spaces or tabs) before <code>EOF</code>. If you want to do it in an <code>if</code>statement, it should look something like this.</p>
<pre><code><span class="hljs-keyword">if</span> [ <span class="hljs-string">"a"</span> == <span class="hljs-string">"a"</span> ]; then  cat &lt;&lt; EOFline1line2line3EOFfi
</code></pre><p>Realize that even the messages themselves are aligned to the left. This is because if you leave them tabbed, the output message shown in the command line will also be tabbed. Also, if <code>EOF</code> is tabbed, the shell will complain about it and usually ends the script there.</p>
<h3 id="heading-flags-options">Flags / Options</h3>
<p>You’ve probably seen some of the scripts or commands that comes with an ability to add flags (and sometimes arguments for the specific flag). Something like <code>git commit -a -m "Some commit message"</code>.</p>
<p>Here’s a quick example of how it looks like (I’ve tried to be as comprehensive as possible with the example.)</p>
<p>In script <code>run_this.sh</code>:</p>
<pre><code><span class="hljs-keyword">while</span> getopts ac: opt; <span class="hljs-keyword">do</span>    <span class="hljs-keyword">case</span> $opt <span class="hljs-keyword">in</span>        a)            echo <span class="hljs-string">"\"a\" was executed."</span>            ;;        c)            echo <span class="hljs-string">"\"c\" was executed with parameter \"$OPTARG\"."</span>            ;;        \?)            echo <span class="hljs-string">"Invalid option: -$opt"</span>            exit <span class="hljs-number">1</span>            ;;        :)            echo <span class="hljs-string">"option -$opt requires an argument."</span>            exit <span class="hljs-number">1</span>            ;;    esacdone
</code></pre><p>Running the command:</p>
<pre><code>./run_this.sh
</code></pre><pre><code>./run_this.sh -a<span class="hljs-string">"a"</span> was executed.
</code></pre><pre><code>./run_this.sh -coption -c requires an argument.
</code></pre><pre><code>./run_this.sh -c abcd<span class="hljs-string">"c"</span> was executed <span class="hljs-keyword">with</span> parameter <span class="hljs-string">"abcd"</span>.
</code></pre><pre><code>./run_this.sh -a -c abc<span class="hljs-string">"a"</span> was executed.<span class="hljs-string">"c"</span> was executed <span class="hljs-keyword">with</span> parameter <span class="hljs-string">"abc"</span>.
</code></pre><pre><code>./run_this.sh -xInvalid option: -x
</code></pre><p>In the above example, the differences between option <code>-a</code> and <code>-c</code> is that in the <code>getopts</code> line, <code>c</code> has a colon (<code>:</code>) following it after therefore telling the program to expect a parameter for the option. Another thing to keep in mind is that the options need to be declared in an alphabetical way. If you declare something like <code>acb</code>, the <code>b</code>declaration would be ignored, and using the <code>-b</code> flag would lead to the error message instead of the <code>b</code> case in the switch condition.</p>
<p>Thanks for reading!</p>
<h3 id="heading-about-me">About me</h3>
<p>I currently work at Facebook as a Software Engineer. I spend some of my free time experimenting and building new things with technologies I find fun and interesting. Follow my exploration journey <a target="_blank" href="https://binhong.me/blog">here</a> or on <a target="_blank" href="https://github.com/binhonglee">GitHub</a>.</p>
<h3 id="heading-references">References</h3>
<ul>
<li><a target="_blank" href="http://wiki.bash-hackers.org/howto/getopts_tutorial">Small getopts tutorial</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/10969953/how-to-output-a-multiline-string-in-bash#10970616">How to output a multiline string in Bash</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
