<?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 - 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 - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 27 Jun 2026 14:19:14 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/shell/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Simple Secure Chat System Using Netcat ]]>
                </title>
                <description>
                    <![CDATA[ In this hands-on tutorial, you'll learn how to harness the power of Netcat to build practical networking tools. We’ll start with basic message transmission. Then you'll progress to creating a file transfer system, and you’ll ultimately develop a secu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-simple-secure-chat-system-with-netcat/</link>
                <guid isPermaLink="false">671a491036e11cfa5033debb</guid>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Netcat ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Hang Hu ]]>
                </dc:creator>
                <pubDate>Thu, 24 Oct 2024 13:18:08 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729729356682/acf8ca42-3aaa-4ca1-9ebc-10f0f658c678.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this hands-on tutorial, you'll learn how to harness the power of Netcat to build practical networking tools.</p>
<p>We’ll start with basic message transmission. Then you'll progress to creating a file transfer system, and you’ll ultimately develop a secure chat application with encryption.</p>
<p>Here’s what we’ll cover:</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-netcat">Install Netcat</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-your-first-network-connection">Your First Network Connection</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-a-simple-file-transfer-tool">How to Build a Simple File Transfer Tool</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-secure-chat-system">How to Create a Secure Chat System</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-practice-your-skills">Practice Your Skills</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we start, you'll need:</p>
<ul>
<li><p>A Linux-based system: I recommend Ubuntu. Alternatively, you can use the <a target="_blank" href="https://labex.io/tutorials/linux-online-linux-playground-372915">Online Linux Terminal</a> if you don't have Linux installed.</p>
</li>
<li><p>Basic terminal knowledge (how to use <code>cd</code> and <code>ls</code>)</p>
</li>
</ul>
<p>Don't worry if you're new to networking - I’ll explain everything as we go!</p>
<h2 id="heading-install-netcat"><strong>Install Netcat</strong></h2>
<p><a target="_blank" href="https://nc110.sourceforge.io/">Netcat</a> is like a digital "pipe" between computers – anything you put in one end comes out the other. Before we start using it, let's get it installed on your system.</p>
<p>Open your terminal and run these commands:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Update your system's package list</span>
sudo apt update

<span class="hljs-comment"># Install Netcat</span>
sudo apt install netcat -y
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583277378/d5fb06c5-3163-4885-b163-2cdde4fa434b.png" alt="Update your system's package list" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<p>To check if the installation worked, run:</p>
<pre><code class="lang-bash">nc -h
</code></pre>
<p>You should see a message starting with "OpenBSD netcat". If you do, great! If not, try running the installation commands again.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583329155/812f32b9-2ca7-41f6-aead-07ffacbf161c.png" alt="check if the installation worked" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<h2 id="heading-your-first-network-connection"><strong>Your First Network Connection</strong></h2>
<p>Before we dive into building tools, let's understand what a network connection actually is. Think of it like a phone call: one person needs to wait for the call (the listener), and another person needs to make the call (the connector).</p>
<p>In networking, we use "ports" to make these connections. You can think of ports like different phone lines – they let multiple conversations happen at the same time.</p>
<p>Let's try making our first connection:</p>
<ol>
<li>Open a terminal window and create a listener:</li>
</ol>
<pre><code class="lang-bash">nc -l 12345
</code></pre>
<p>What did we just do? The <code>-l</code> tells Netcat to "listen" for a connection, and <code>12345</code> is the port number we chose. Your terminal will look like it's frozen – that's normal! It's waiting for someone to connect.</p>
<ol start="2">
<li>Open another terminal window and connect to your listener:</li>
</ol>
<pre><code class="lang-bash">nc localhost 12345
</code></pre>
<p>Here, <code>localhost</code> means "this computer" – we're connecting to ourselves for practice. If you want to connect to another computer, you can replace <code>localhost</code> with its IP address.</p>
<p>Now try typing a message (like "hi") in either window and press Enter. Cool, right? The message appears in the other window! This is exactly how basic network communication works.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583496294/da70a4bc-5626-493c-8a52-385b708593f4.png" alt="making our first connection" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<p>To stop the connection, press <code>Ctrl+C</code> in both windows.</p>
<h3 id="heading-what-just-happened"><strong>What Just Happened?</strong></h3>
<p>You just created your first network connection! The first terminal was like someone waiting by a phone, and the second terminal was like someone calling that phone. When they connected, they could send messages back and forth.</p>
<h2 id="heading-how-to-build-a-simple-file-transfer-tool"><strong>How to Build a Simple File Transfer Tool</strong></h2>
<p>Now that we understand basic connections, let's build something more useful: a tool to transfer files between computers.</p>
<p>First, let's create a test file to send:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a file with some content</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"This is my secret message"</span> &gt; secret.txt
</code></pre>
<p>To transfer this file, we'll need two terminals again, but this time we'll use them differently:</p>
<ol>
<li>In the first terminal, set up the receiver:</li>
</ol>
<pre><code class="lang-bash">nc -l 12345 &gt; received_file.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583969994/d3159a2f-37f7-4cab-a23b-3788ed85876f.png" alt="transfer file" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<p>This tells Netcat to:</p>
<ul>
<li><p>Listen for a connection (<code>-l</code>)</p>
</li>
<li><p>Save whatever it receives to a file called <code>received_file.txt</code> (<code>&gt;</code>)</p>
</li>
</ul>
<ol start="2">
<li>In the second terminal, send the file:</li>
</ol>
<pre><code class="lang-bash">nc localhost 12345 &lt; secret.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583998676/ab865ded-626a-47aa-9df6-83e56aa5f5d1.png" alt="send the file" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<p>The <code>&lt;</code> tells Netcat to send the contents of our file.</p>
<ol start="3">
<li>Press Ctrl+C in both terminals to stop the transfer. Then check if it worked:</li>
</ol>
<pre><code class="lang-bash">cat received_file.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584030360/32fa9916-ffdb-49da-abcf-57569c9b2f79.png" alt="received file" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<p>You should see your message!</p>
<p>This is similar to our chat system, but instead of typing messages, we're:</p>
<ol>
<li><p>Taking content from a file</p>
</li>
<li><p>Sending it through our network connection</p>
</li>
<li><p>Saving it to a new file on the other end</p>
</li>
</ol>
<p>Think of it like sending a document through a fax machine!</p>
<h2 id="heading-how-to-create-a-secure-chat-system"><strong>How to Create a Secure Chat System</strong></h2>
<p>Our previous examples sent everything as plain text – anyone could read it if they intercepted the connection. Let's make something more secure by adding encryption.</p>
<p>First, let's understand what encryption does:</p>
<ul>
<li><p>It's like putting your message in a locked box</p>
</li>
<li><p>Only someone with the right key can open it</p>
</li>
<li><p>Even if someone sees the box, they can't read your message</p>
</li>
</ul>
<p>We'll create two scripts: one for sending messages and one for receiving them.</p>
<ol>
<li>Create the sender script:</li>
</ol>
<pre><code class="lang-bash">nano secure_sender.sh
</code></pre>
<p>Copy this code into the file:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Secure Chat - Type your messages below"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Press Ctrl+C to exit"</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
  <span class="hljs-comment"># Get the message</span>
  <span class="hljs-built_in">read</span> message

  <span class="hljs-comment"># Encrypt and send it</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$message</span>"</span> | openssl enc -aes-256-cbc -salt -base64 \
    -pbkdf2 -pass pass:chatpassword 2&gt;/dev/null | \
    nc -N localhost 12345
<span class="hljs-keyword">done</span>
</code></pre>
<p>This script will:</p>
<ol>
<li><p>Read messages from user input.</p>
</li>
<li><p>Encrypt them using OpenSSL's AES-256-CBC encryption (a strong encryption standard).</p>
</li>
<li><p>Send the encrypted message to the specified port.</p>
</li>
</ol>
<p>Press Ctrl+X, then Y, then Enter to save.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584825701/bcd3c3fb-5cd5-40f7-8105-14d1fff069ec.png" alt="Create the sender script" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<ol start="2">
<li>Create the receiver script:</li>
</ol>
<pre><code class="lang-bash">nano secure_receiver.sh
</code></pre>
<p>Copy this code:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Waiting for messages..."</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
  <span class="hljs-comment"># Receive and decrypt messages</span>
  nc -l 12345 | openssl enc -aes-256-cbc -d -salt -base64 \
    -pbkdf2 -pass pass:chatpassword 2&gt;/dev/null
<span class="hljs-keyword">done</span>
</code></pre>
<p>This script will:</p>
<ol>
<li><p>Listen for incoming encrypted messages.</p>
</li>
<li><p>Decrypt them using the same encryption key.</p>
</li>
<li><p>Display the decrypted messages.</p>
</li>
</ol>
<p>Save this file too.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584787785/c1e329ad-cbbe-49e8-918f-25d683884972.png" alt="Create the receiver script" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<ol start="3">
<li>Make both scripts executable:</li>
</ol>
<pre><code class="lang-bash">chmod +x secure_sender.sh secure_receiver.sh
</code></pre>
<ol start="4">
<li>Try it out:</li>
</ol>
<ul>
<li><p>In one terminal: <code>./secure_receiver.sh</code></p>
</li>
<li><p>In another terminal: <code>./secure_sender.sh</code></p>
</li>
</ul>
<p>Type a message in the sender terminal. The receiver will show your decrypted message!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584834464/1f902a94-3a79-404b-bc9f-af9d8d2471e0.png" alt="Type a message in the sender terminal" class="image--center mx-auto" width="1920" height="1440" loading="lazy"></p>
<h3 id="heading-enhancing-our-chat-system"><strong>Enhancing Our Chat System</strong></h3>
<p>Now that we have a working basic chat system, let's make it more user-friendly and informative. We'll add features like timestamps, color-coded messages, and encryption status updates. This enhanced version will help you better understand what's happening during the encryption and transmission process.</p>
<p>If you're comfortable with the basic version, try this improved version:</p>
<ol>
<li>Create an enhanced sender script (save it as <code>secure_sender_v2.sh</code>):</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Set up color codes for better visibility</span>
GREEN=<span class="hljs-string">'\033[0;32m'</span>
BLUE=<span class="hljs-string">'\033[0;34m'</span>
NC=<span class="hljs-string">'\033[0m'</span> <span class="hljs-comment"># No Color</span>

<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Secure Chat Sender - Started at <span class="hljs-subst">$(date)</span><span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Type your messages below. Press Ctrl+C to exit<span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
    <span class="hljs-comment"># Show prompt with timestamp</span>
    <span class="hljs-built_in">echo</span> -ne <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>[<span class="hljs-subst">$(date +%H:%M:%S)</span>]<span class="hljs-variable">${NC}</span> Your message: "</span>

    <span class="hljs-comment"># Get the message</span>
    <span class="hljs-built_in">read</span> message

    <span class="hljs-comment"># Skip if message is empty</span>
    <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$message</span>"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">continue</span>
    <span class="hljs-keyword">fi</span>

    <span class="hljs-comment"># Add timestamp to message</span>
    timestamped_message=<span class="hljs-string">"[<span class="hljs-subst">$(date +%H:%M:%S)</span>] <span class="hljs-variable">$message</span>"</span>

    <span class="hljs-comment"># Show encryption status</span>
    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Encrypting and sending message...<span class="hljs-variable">${NC}</span>"</span>

    <span class="hljs-comment"># Encrypt and send it, showing the encrypted form</span>
    encrypted=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$timestamped_message</span>"</span> | openssl enc -aes-256-cbc -salt -base64 \
        -pbkdf2 -iter 10000 -pass pass:chatpassword 2&gt;/dev/null)

    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Encrypted form:<span class="hljs-variable">${NC}</span> <span class="hljs-variable">${encrypted:0:50}</span>..."</span> <span class="hljs-comment"># Show first 50 chars</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$encrypted</span>"</span> | nc -N localhost 12345

    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Message sent successfully!<span class="hljs-variable">${NC}</span>"</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>
<span class="hljs-keyword">done</span>
</code></pre>
<ol start="2">
<li>Create an enhanced receiver script (save as <code>secure_receiver_v2.sh</code>):</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Set up color codes for better visibility</span>
GREEN=<span class="hljs-string">'\033[0;32m'</span>
BLUE=<span class="hljs-string">'\033[0;34m'</span>
YELLOW=<span class="hljs-string">'\033[1;33m'</span>
NC=<span class="hljs-string">'\033[0m'</span> <span class="hljs-comment"># No Color</span>

<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Secure Chat Receiver - Started at <span class="hljs-subst">$(date)</span><span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Waiting for messages... Press Ctrl+C to exit<span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
    <span class="hljs-comment"># Receive and show the encrypted message</span>
    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Waiting for next message...<span class="hljs-variable">${NC}</span>"</span>

    encrypted=$(nc -l 12345)

    <span class="hljs-comment"># Skip if received nothing</span>
    <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$encrypted</span>"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">continue</span>
    <span class="hljs-keyword">fi</span>

    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${YELLOW}</span>Received encrypted message:<span class="hljs-variable">${NC}</span> <span class="hljs-variable">${encrypted:0:50}</span>..."</span> <span class="hljs-comment"># Show first 50 chars</span>
    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Decrypting...<span class="hljs-variable">${NC}</span>"</span>

    <span class="hljs-comment"># Decrypt and display the message</span>
    decrypted=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$encrypted</span>"</span> | openssl enc -aes-256-cbc -d -salt -base64 \
        -pbkdf2 -iter 10000 -pass pass:chatpassword 2&gt;/dev/null)

    <span class="hljs-comment"># Check if decryption was successful</span>
    <span class="hljs-keyword">if</span> [ $? -eq 0 ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Decrypted message:<span class="hljs-variable">${NC}</span> <span class="hljs-variable">$decrypted</span>"</span>
    <span class="hljs-keyword">else</span>
        <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"\033[0;31mError: Failed to decrypt message<span class="hljs-variable">${NC}</span>"</span>
    <span class="hljs-keyword">fi</span>

    <span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>
<span class="hljs-keyword">done</span>
</code></pre>
<ol start="3">
<li>Make the enhanced scripts executable:</li>
</ol>
<pre><code class="lang-bash">chmod +x secure_sender_v2.sh secure_receiver_v2.sh
</code></pre>
<p>Try running both versions to see how the additional feedback helps you better understand the encryption and communication process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729585592733/01d25154-37a9-4c14-95ac-410c513956b9.png" alt="Enhancing Our Chat System" class="image--center mx-auto" width="1920" height="1080" loading="lazy"></p>
<p>The enhanced version (v2) adds several improvements:</p>
<ul>
<li><p>Colorized output for better readability.</p>
</li>
<li><p>Timestamps for each message.</p>
</li>
<li><p>Status updates showing the encryption/decryption process.</p>
</li>
<li><p>Error handling for failed decryption attempts.</p>
</li>
<li><p>Preview of encrypted messages before sending/after receiving.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This tutorial taught you how to use Netcat as a versatile networking tool. We started with basic message sending, progressed to building a simple file transfer system, and then created a secure chat system with encryption.</p>
<p>You've gained hands-on experience with:</p>
<ul>
<li><p>Setting up network listeners and connections</p>
</li>
<li><p>Transferring files securely between systems</p>
</li>
<li><p>Implementing basic encryption for secure communication</p>
</li>
<li><p>Adding user-friendly features like timestamps and status updates</p>
</li>
</ul>
<p>The skills you've learned here form a solid foundation for understanding network communication and can be applied to more complex networking projects. To practice the operations from this tutorial, try <a target="_blank" href="https://labex.io/labs/linux-using-netcat-for-simple-network-communication-392039">the interactive hands-on lab</a>.</p>
<h2 id="heading-practice-your-skills"><strong>Practice Your Skills</strong></h2>
<p>Now that you've learned the basics of Netcat and built a secure chat system, let's put your skills to the test with a real-world scenario. Try the "<a target="_blank" href="https://labex.io/labs/linux-receive-messages-using-netcat-392102"><strong>Receive Messages Using Netcat</strong></a>" lab challenge where you'll play the role of a junior interstellar communications analyst. Your mission: intercept and log signals from an alien civilization using your newfound Netcat knowledge.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Do Zsh Configuration Files Work? ]]>
                </title>
                <description>
                    <![CDATA[ Beginners often get confused when configuring Zsh shell on a Mac. Zsh shell offers four configuration files with no discernible differences. Particularly, ~/.zshrc and ~/.zprofile appear to be identical, leaving us wondering which one to use.  In thi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-do-zsh-configuration-files-work/</link>
                <guid isPermaLink="false">66ba15ffad32b828c4c5be04</guid>
                
                    <category>
                        <![CDATA[ macOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                    <category>
                        <![CDATA[ zsh ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Kehoe ]]>
                </dc:creator>
                <pubDate>Tue, 09 Jan 2024 20:37:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/pexels-mike-468229-1181772.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Beginners often get confused when configuring Zsh shell on a Mac.</p>
<p>Zsh shell offers four configuration files with no discernible differences. Particularly, <code>~/.zshrc</code> and <code>~/.zprofile</code> appear to be identical, leaving us wondering which one to use. </p>
<p>In this article, you'll learn the difference and a simple guideline for your shell configuration.</p>
<h2 id="heading-why-do-you-need-configuration">Why Do you Need Configuration?</h2>
<p>For programming on a Mac, the Terminal application is an essential tool in your development environment. The Terminal is a command-line interface (CLI) that allows you to interact with the operating system and run commands. </p>
<p>The Terminal or console gives you access to the Unix command line, or shell. </p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Z_shell">Zsh</a>, also known as Z shell, is a program that runs in the Terminal, interprets Unix commands, and interacts with the operating system. Zsh is the default shell program on MacOS.</p>
<p>Before you get started with programming on the Mac, you'll need to configure the shell. There are optional and convenient settings, such as aliases for hard-to-remember commands and a custom prompt that can display the directory you're in, among other things. </p>
<p>There are also some critical environment variables that make programs available or alter shell behavior. The <code>EDITOR</code> environment variable, for example, can set your preferred text editor. Oftentimes, when installing a programming language or software utilities, you need to set the <code>PATH</code> environment variable..</p>
<h2 id="heading-where-to-start">Where to Start</h2>
<p>Zsh configuration files are kept in the user's home directory and are named with a dot as the first character to keep them hidden by default. </p>
<p>Zsh recognizes four different configuration files in the user's home directory: <code>~/.zshenv</code>, <code>~/.zprofile</code>, <code>~/.zshrc</code>, and <code>~/.zlogin</code>. </p>
<p>This is where Zsh configuration becomes puzzling, even for experienced developers. Tutorials rarely explain the differences, especially between the <code>zprofile</code> and <code>zshrc</code> files, leaving curious developers scratching their heads and blindly following instructions.</p>
<h3 id="heading-how-is-the-shell-used">How is the Shell Used?</h3>
<p>To understand the differences among Zsh configuration files, consider various shell uses, which can be classified as interactive or non-interactive, login or non-login sessions.</p>
<ol>
<li>On macOS, each new terminal session is treated as a login shell, so opening any terminal window starts an interactive login session. Also, a system administrator who connects to a remote server via SSH initiates an interactive login session.</li>
<li>If a terminal window is already open and you run the command <code>zsh</code> to start a subshell, it will be interactive and non-login. Beginners rarely use subshells.</li>
<li>Automated shell scripts run without login or any user prompting. These are non-interactive and non-login.</li>
<li>Few people ever encounter a non-interactive login shell session. It requires starting a script with a special flag or piping output of a command into an SSH connection.</li>
</ol>
<h3 id="heading-how-do-the-configuration-files-work">How do the Configuration Files Work?</h3>
<p>These use cases necessitate different shell configurations, which explains why Zsh supports four different configuration files. Here's how the configuration files are used:</p>
<ul>
<li><code>~/.zshenv</code>: This is loaded universally for all types of shell sessions (interactive or non-interactive, login or non-login). It is the only configuration file that gets loaded for non-interactive and non-login scripts like cron jobs. However, macOS overrides this for <code>PATH</code> settings for interactive shells.</li>
<li><code>~/.zprofile</code>: Loaded for login shells (both interactive and the rare non-interactive sessions). MacOS uses this to set up the shell for any new terminal window. Subshells that start within the terminal window inherit settings but don't load <code>~/.zprofile</code> again.</li>
<li><code>~/.zshrc</code>: Loaded only for interactive shell sessions. It is loaded whenever you open a new terminal window or launch a subshell from a terminal window.</li>
<li><code>~/.zlogin</code>: Only used for login shell configurations, loaded after <code>.zprofile</code>. This is loaded whenever you open a new terminal window.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/zsh-diagram.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-use-each-file">How to Use Each File</h2>
<p>With that in mind, let's consider which configuration files you should use.</p>
<ul>
<li><code>~/.zshenv</code>: It is universally loaded, so you could use it to configure the shell for automated processes like cron jobs. However, it is best to explicitly set up environmental variables for automated processes in scripts and leave nothing to chance. As a beginner, you will not use this configuration file. In fact, few experienced macOS developers use it.</li>
<li><code>~/.zprofile</code>: Homebrew recommends setting the <code>PATH</code> variable here. There's a reason <code>PATH</code> should be set in  <code>~/.zprofile</code> and not the universal <code>~/.zshenv</code>file: the macOS runs a utility <code>path_helper</code> (from <code>/etc/zprofile</code>) that sets the <code>PATH</code> order before <code>~/.zprofile</code> is loaded.</li>
<li><code>~/.zshrc</code>: This is the configuration file that most developers use. Use it to set aliases and a custom prompt for the terminal window. You can also use it to set the <code>PATH</code> (which many people do) but <code>~/.zprofile</code> is preferred.</li>
<li><code>~/.zlogin</code>: This is rarely used. Only important in managing the order of initialization tasks for login shells in complex environments. It can be used to display messages or system data.</li>
</ul>
<h2 id="heading-how-to-avoid-complications">How to Avoid Complications</h2>
<p>These configurations may appear complicated. It made sense in the early days of computing to start time-consuming processes at login and not have them repeat when a new terminal was launched.</p>
<p>MacOS now launches any new terminal window as a login shell, loading both  <code>~/.zprofile</code> and <code>~/.zshrc</code> files without concern for the shell startup time. So why not use one Zsh configuration file? A bow to history, plus configuration customization for the experts.</p>
<p>The key advantage of the <code>~/.zprofile</code> file (versus  <code>~/.zshenv</code>) is that it sets environment variables such as <code>PATH</code> without override from macOS. The  <code>~/.zshrc</code> file could be used for the same but, by convention and design, is intended for customizing the look and feel of the interactive terminal.</p>
<h2 id="heading-keep-it-simple">Keep It Simple</h2>
<p>If you're looking for simple guidelines, here's the current best practice.</p>
<ul>
<li>Use <code>~/.zprofile</code> to set the <code>PATH</code> and <code>EDITOR</code> environment variables.</li>
<li>Use <code>~/.zshrc</code> for aliases and a custom prompt, tweaking the appearance and behavior of the terminal.</li>
<li>If you write automated shell scripts, check and set environment variables in the script.</li>
</ul>
<h2 id="heading-more-information">More Information</h2>
<p>I've written other guides that go into detail about the following:</p>
<ul>
<li><a target="_blank" href="https://mac.install.guide/terminal/index.html">Mac Terminal</a></li>
<li><a target="_blank" href="https://mac.install.guide/terminal/configuration.html">Shell Configuration</a></li>
<li><a target="_blank" href="https://mac.install.guide/terminal/path.html">Mac PATH</a>.</li>
</ul>
<p>If you're just getting started, you'll need to know <a target="_blank" href="https://mac.install.guide/terminal/open.html">How to Open Mac Terminal</a> and <a target="_blank" href="https://mac.install.guide/commandlinetools/index.html">Install Xcode Command Line Tools</a>.</p>
<p>Configuring the Zsh shell is a critical step in preparing your Mac development environment. With your development environment set up, you'll be prepared for any tutorial you'll find on freeCodeCamp.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ CLI Shells – A Brief History of Human-Computer Interfaces ]]>
                </title>
                <description>
                    <![CDATA[ By Chidiadi Anyanwu A computer is basically a piece of electronic circuitry that performs tasks as instructed by its users. But for a human to interact with this hardware, they must really know and understand how it works. The person must also know t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/shells-a-history-of-human-computer-interfaces/</link>
                <guid isPermaLink="false">66d45dd7868774922c884fcd</guid>
                
                    <category>
                        <![CDATA[ cli ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Computer Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chidiadi Anyanwu ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jul 2023 16:45:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Evernote-cli-geeknote.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Chidiadi Anyanwu</p>
<p>A computer is basically a piece of electronic circuitry that performs tasks as instructed by its users.</p>
<p>But for a human to interact with this hardware, they must really know and understand how it works. The person must also know the order in which to give the computer various tasks to produce a meaningful result.</p>
<p>But most of us don't know these things. What happened?</p>
<p>In this article, we're going to look at:</p>
<ul>
<li><p>The history of early computing</p>
</li>
<li><p>How operating systems were developed</p>
</li>
<li><p>Modern operating systems</p>
</li>
<li><p>The development of kernels and shells</p>
</li>
<li><p>The history of shells</p>
</li>
<li><p>Why CLI tools are still important</p>
</li>
</ul>
<h2 id="heading-the-early-days-of-computers">The Early Days of Computers</h2>
<p>In the 1800's, computers were mostly used to work on large amounts of numerical data. They were basically programmable calculators the size of small factories.</p>
<p>The data they worked on were also very physical. They were manually fed as punched cards into the machine's card readers. The computers were then programmed by physically rewiring cables, plugboards, and switches to determine what operations would be carried out on the input data. Some of the computers even processed logic through partially mechanical means.</p>
<p>Plugboards allowed you write (or wire) a program and store it so when you needed that program, you'd remove the current plugboard and install a new one. The output of the programs were printed out by line printers, saved on tapes, or punched on cards.</p>
<p>These programming and memory technologies were used in many forms of technological designs.</p>
<p>For example, the Enigma machine which was used to scramble letters and encipher top secret military and diplomatic communication had a plugboard you would rewire to change settings.</p>
<p>The IBM International Daily Dial Attendance Recorder also counted and recorded staff attendance on punched cards. These were more special-purpose equipment.</p>
<h2 id="heading-early-operating-systems">Early Operating Systems</h2>
<p>The first-ever speech synthesis was done in 1962 on an IBM 704, a computer without an operating system.</p>
<p>At the time of the first computers, nobody ever thought of operating systems. People wrote their programs in machine language (or wired them on plugboards) and ran them. There was no way to run two programs at the same time or perform error detection/correction. Your program ran until it either crashed or completed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/IBM_Electronic_Data_Processing_Machine_-_GPN-2000-001881-IBM-704.jpg" alt="Picture of a man and a woman operating the IBM 704 in 1957." width="600" height="400" loading="lazy"></p>
<p><em>IBM 704 computer with two operators in 1957</em></p>
<p>Initially, computers didn't ship with any software. Later on, IBM included FORTRAN and COBOL compilers in their mainframes. Then came 'resident monitors,' the precursor to operating systems. They literally got the name because they were software that resided in the company's memory and monitored tasks. They basically performed tasks like cleaning up after programs and helping to sequence jobs on the computers.</p>
<p>The first operating systems were made by computer owners who were tired of under-utilizing their computers. They didn't want to have to wait for a program to complete before they manually loaded in another set of data and programs.</p>
<p>One of these early operating systems was the Input/Output System of General Motors and North American Aviation (GM-NAA I/O). Its main aim was to execute the next program automatically after the current one was finished (batch processing). It was created in 1956, and is known as the first-ever working operating system.</p>
<p>IBM later modified one of its customer's operating systems and distributed it as IBSYS. Then, IBM thought that it wasn't good for different computers to have different (machine language) instruction sets, so they stopped all production and started a new line called System/360.</p>
<p>With this, they aimed to build just one operating system for all their computers. It didn't quite go as planned, so they ended up with a family of operating systems, OS/360.</p>
<p>OS/360 included features like time-sharing, error detection/correction, and device management, which are all features implemented in modern operating systems. The OS/360 was introduced in 1964 and was in use until 1977.</p>
<p>Early time-sharing technologies enabled multiple people to access the same mainframe from their different terminals at once. The first computer terminals were teletypewriters (or teletypes). Teletypes were developed around the 1830's but weren't used as computer terminals until the 1970's.</p>
<h2 id="heading-modern-operating-systems">Modern Operating Systems</h2>
<p>The MULTiplexed Information and Computing Service (MULTICS) operating system was initially developed for General Electric's 645 mainframe, and later Honeywell's mainframes when they bought over GE's computer division.</p>
<p>It was jointly developed in 1964 by GE, MIT, and Bell Labs, mainly as a successor to the Compatible Time-Sharing System (CTSS).</p>
<p>It came with a lot of new ideas to the computing world like access control, dynamic linking, support for ASCII, and dynamic reconfiguration.</p>
<p>Dynamic reconfiguration allowed the operators to remove and add memories and CPUs without logging out or disrupting users. With the advent of the Compatible Time-Sharing System (CTSS), computers were looked at as a utility.</p>
<p>The idea was that computers were too big and expensive and could be used by only one person at a time. But what if that expensive hardware could be used more efficiently by allowing more than one person to use them at the same time? That way, the computer could become a public utility, accessed from home with terminals.</p>
<p>With a public utility, you need to be able to carry out maintenance on different components without disrupting the service. That was the usefulness of dynamic reconfiguration.</p>
<p>That idea of computers becoming a public utility seems to have lived on with the use of servers, and now, cloud computing.</p>
<p>At a point, MULTICS didn't work out and the companies went their separate ways. Ken Thompson, one of the programmers, later described MULTICS as 'over-designed,' 'overbuilt,' and close to unusable. In an interview with Peter Seibel, he said that the things he liked enough to take from it were the hierarchical filesystem and the shell.</p>
<p>He later went on to create the UNIX operating system with Dennis Ritchie.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Timeline-Computers.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-the-development-of-kernels-and-shells">The Development of Kernels and Shells</h2>
<p>One of the major features of the UNIX operating system was the splitting of the operating system into shell and kernel. The OS kernel was then meant to handle all the system calls, while the shell was used to access the system's services without exposing the inner workings of the operating system.</p>
<p>This concept was first introduced by French computer scientist Louis Pouzin in 1965. He also coined the term shell. This is how he described it in a document titled, <a target="_blank" href="https://people.csail.mit.edu/saltzer/Multics/Multics-Documents/MDN/MDN-4.pdf">The SHELL: A Global Tool for Calling and Chaining Procedures in the System</a>.</p>
<blockquote>
<p>We may envision a common procedure called automatically by the supervisor whenever a user types in some message at his console . . . we shall refer to that procedure as the "SHELL".</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Louis-Pouzin-Shell-Document-Definition.png" alt="Louis Pouzin Shell Document Definitionpng" width="600" height="400" loading="lazy"></p>
<p><em>Louis Pouzin's Document on Shells</em></p>
<p>According to the document, when the user types in a command, the supervisor initiates a new stack to save the command, then calls the shell with the command as an argument.</p>
<p>He also envisioned a future where people created their own shells and used them without having to meddle with the underlying structure of the shell.</p>
<blockquote>
<p>"An important facility is that the SHELL being itself a common procedure may be replaced by a private one supplied by the user. On that way, not only a particular procedure can be replaced on user's choice, but all conventions about typing commands may be tailor-made to user's wishes just by providing his own SHELL."</p>
</blockquote>
<p>This idea was first implemented in MULTICS, and is one of the only things Ken Thompson admitted to liking enough to take from the project.</p>
<p>Now, in modern operating systems, the shell is the software that lets you communicate with the operating system, and access the OS services which are things like program execution, file management, and I/O management. It could be a command-line shell (CLI) or it could be a graphical user interface (GUI).</p>
<p>The kernel is the part that handles all the system calls, manages computer resources like memory, CPU, and storage, and handles timesharing between processes.</p>
<h2 id="heading-history-of-cli-shells">History of CLI Shells</h2>
<p>Shells as we know them now really began with UNIX, and one of the first was the Thompson shell.</p>
<h3 id="heading-thompson-shell-1971">Thompson Shell (1971)</h3>
<p>Ken Thompson, of course, went on to create his own shell. It was a simple command interpreter, not designed for scripting. It introduced the &lt; &gt; symbols for redirecting the input or output of a command, and the | symbol for piping.</p>
<h3 id="heading-c-shell-1978">C Shell (1978)</h3>
<p>The C Shell (or csh) was created by Bill Joy and enabled scripting. The objective was to create a command language that looked more like the C programming language.</p>
<h3 id="heading-bourne-shell-1979">Bourne Shell (1979)</h3>
<p>Stephen Bourne started work on the Bourne Shell in 1976 as a replacement for the Thompson Shell. It was intended as a scripting language. One of the major goals was to enable using scripts as filters.</p>
<h3 id="heading-korn-shell-1983">Korn Shell (1983)</h3>
<p>Developed by David Korn, the Korn Shell was based on source code from the Bourne Shell, and attempted to integrate the features of C Shell and Bourne Shell. It is <a target="_blank" href="https://en.wikipedia.org/wiki/POSIX">POSIX.2</a> compliant.</p>
<h3 id="heading-bourne-again-shell-aka-bash-1989">Bourne Again SHell aka BASH (1989)</h3>
<p>BASH was written by Brian Fox in 1989 and released under the GNU license as a free and open-source version of the Bourne Shell.</p>
<p>It was one of the first programs Linus Torvalds ported to Linux and is the default shell for most Linux distributions. It was built for scripting and is <a target="_blank" href="https://en.wikipedia.org/wiki/POSIX">POSIX</a> compliant.</p>
<h3 id="heading-z-shell-1990">Z Shell (1990)</h3>
<p>The Z Shell (or Zsh) was created by Paul Falstad as an extended and improved Bourne Shell. The name was derived from the name of a teaching assistant at Paul's university named Zhong Shao.</p>
<p>It also enables scripting and is aesthetically superior to Bash. It supports plugins and extensions, auto-completion, and some other globing capabilities that are unavailable in Bash.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Timeline-Shells-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>There are many other popular shells used today, but I'm not going to talk about them.</p>
<p>All these shells mentioned did not apply to Windows (until recently). Windows had two command-line shells: Command Prompt (cmd) and PowerShell. The PowerShell was created as an extension to Command Prompt. It supports cmdlets, scripting, piping, and many more features.</p>
<p>Then in 2019, that changed with Windows Terminal, a new terminal emulator for Windows that can run Bash on what is called Windows Subsystem for Linux (WSL). It also supports Command Prompt, PowerShell, and Azure Cloud shell out-of-the-box.</p>
<h2 id="heading-why-are-these-cli-tools-important-when-we-have-graphical-user-interfaces-guis">Why Are These CLI Tools Important When We Have Graphical User Interfaces (GUIs)?</h2>
<p>You may wonder why we would take the pains to go through this whole evolution and yet still love to use CLI tools and shells. What's so interesting about typing commands into terminals?</p>
<p>The first and most compelling reason is that CLI tools are lightweight because they're text-based. In cases where you have servers and other devices where you need to optimize the use of resources, it's not very wise to use up most of the resources to run GUI interfaces.</p>
<p>Using the CLI can also provide you with a great deal of flexibility and speed that you won't get with a GUI. For example, you may want to search for all the images in a folder with 1000 files and rename them in a certain order. Doing that with your GUI will be time-consuming and maybe frustrating. With the CLI, you can just type a few commands.</p>
<p>Scripts are another important feature. Sometimes, there are tasks you want to carry out multiple times and you don't want to have to navigate through menus all the time or even type commands multiple times. You can write scripts that you run to automatically carry out the tasks repetitively.</p>
<p>In cases where you have to access devices remotely, like web servers or network devices, the CLI is also the most favoured method. Also, for some tasks, it's just easier to do them with a few commands than using your GUI—updating your apps on Linux for example.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>We've really come a long way from purely mechanical computers to purely electronic computers. The way we interact with computers has changed over the decades, but command-line interfaces aren't going anywhere soon.</p>
<p>Thanks for reading. I hope you enjoyed this article. You can <a target="_blank" href="https://www.linkedin.com/in/chidiadi-anyanwu">connect with me on LinkedIn.</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
