<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Chen</title>
    <description>The latest articles on DEV Community by James Chen (@typinghare).</description>
    <link>https://dev.to/typinghare</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3707749%2F53d6d2d7-33f1-49ad-b294-7d738d34c009.jpg</url>
      <title>DEV Community: James Chen</title>
      <link>https://dev.to/typinghare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/typinghare"/>
    <language>en</language>
    <item>
      <title>[Tutorial] Learning Paths in Linux</title>
      <dc:creator>James Chen</dc:creator>
      <pubDate>Tue, 02 Jun 2026 16:00:09 +0000</pubDate>
      <link>https://dev.to/typinghare/tutorial-learning-paths-in-linux-4ja9</link>
      <guid>https://dev.to/typinghare/tutorial-learning-paths-in-linux-4ja9</guid>
      <description>&lt;p&gt;Have you ever encountered &lt;code&gt;FileNotFoundError&lt;/code&gt; or similar errors and wondered how to address them? Have you been stuck in situations where the code doesn't work after being moved to another device? This post will cover everything you need to know about &lt;strong&gt;paths in Linux&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  📌 &lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
After reading this post, readers will be able to:

&lt;ul&gt;
&lt;li&gt;Differentiate between relative and absolute paths; comprehend the relationship among the current working directory, relative paths, and absolute paths.&lt;/li&gt;
&lt;li&gt;Perform path resolution and path normalization; recognize the roles of &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;..&lt;/code&gt; in a path.&lt;/li&gt;
&lt;li&gt;Execute basic Linux commands for navigating the filesystem.&lt;/li&gt;
&lt;li&gt;Understand path-related environment variables; configure environment paths.&lt;/li&gt;
&lt;li&gt;Understand how the shell expands &lt;code&gt;~&lt;/code&gt; to the user's home directory.&lt;/li&gt;
&lt;li&gt;Understand how the shell locates an executable through the &lt;code&gt;PATH&lt;/code&gt; variable; inspect executable locations with &lt;code&gt;which&lt;/code&gt; and &lt;code&gt;which -a&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Troubleshoot "File Not Found" errors in IDEs by inspecting the current working directory.

&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Absolute Path, Relative Path, and Working Directory
&lt;/h2&gt;

&lt;p&gt;Imagine you are at the reptile house in a zoo, and you want to navigate to the aviary. You open Google Maps and find a path, following which you arrive at the aviary.&lt;/p&gt;

&lt;p&gt;But all of a sudden, your phone is dead, and you cannot navigate to the aquarium from the aviary. But you happen to know the path from every place to the entrance gate and vice versa. So what you do is first go back to the entrance gate, and then head to the aquarium.&lt;/p&gt;

&lt;p&gt;In Linux, the reptile house in the first example is the &lt;strong&gt;current working directory (cwd)&lt;/strong&gt;, and the path from the reptile house to the aviary is a &lt;strong&gt;relative path&lt;/strong&gt;. In the second example, the entrance gate corresponds to the &lt;strong&gt;system root directory&lt;/strong&gt;, and the paths from the entrance gate to all places are &lt;strong&gt;absolute paths&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In Linux, the system root directory is represented as a slash &lt;code&gt;/&lt;/code&gt;. If you are a Windows user, keep in mind that there are no drives (e.g., C drive) in Linux. Every absolute path starts with a slash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt;: system root directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/home/james&lt;/code&gt;: James's home directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/etc/nginx/nginx.conf&lt;/code&gt;: NGINX configuration file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every file or directory is associated with a unique absolute path for the operating system to locate. For instance, to locate the &lt;code&gt;/home/james&lt;/code&gt; directory, Linux starts from the system root directory, then goes to the &lt;code&gt;home&lt;/code&gt; directory, and finally arrives at the &lt;code&gt;james&lt;/code&gt; directory. This procedure is deterministic.&lt;/p&gt;

&lt;p&gt;However, in projects, we often see paths that do not start with a slash. Those are &lt;strong&gt;relative paths&lt;/strong&gt;, for instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/main.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;internal/service/user.go&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you understand how the system locates a file with an absolute path, you may now wonder: "To locate a file with a relative path, where should the system start from?"&lt;/p&gt;

&lt;p&gt;The answer is the current working directory (also referred to as "present working directory"). In the example at the beginning, if you want to check the path to the aviary, you must first tell Google Maps where you are currently.&lt;/p&gt;

&lt;p&gt;In the following sections, we will discuss how to determine the current working directory. But now, let's figure out how Linux locates a file with the current working directory and a relative path.&lt;/p&gt;

&lt;p&gt;We already know that the procedure of locating a file with an absolute path is deterministic. Therefore, we just need to combine the current working directory and the relative path into an absolute path. This is referred to as &lt;strong&gt;path resolution&lt;/strong&gt;. For example, if we try to access &lt;code&gt;src/main.py&lt;/code&gt; from &lt;code&gt;/home/james/memo&lt;/code&gt;, the operating system first concatenates them into &lt;code&gt;/home/james/memo/src/main.py&lt;/code&gt;, and accesses the file with this absolute path.&lt;/p&gt;

&lt;p&gt;Every directory in Linux comes with these two special items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.&lt;/code&gt; refers to the &lt;strong&gt;current directory&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;..&lt;/code&gt; refers to the &lt;strong&gt;parent directory&lt;/strong&gt;. It allows navigation one level up in the directory hierarchy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, &lt;code&gt;internal/service/./user.go&lt;/code&gt; is equivalent to &lt;code&gt;internal/service/user.go&lt;/code&gt; because &lt;code&gt;.&lt;/code&gt; can be removed without altering the path. &lt;code&gt;/home/james/memo/../coursework&lt;/code&gt; is equivalent to &lt;code&gt;/home/james/coursework&lt;/code&gt; because &lt;code&gt;..&lt;/code&gt; moves up one directory from &lt;code&gt;/home/james/memo&lt;/code&gt; to &lt;code&gt;/home/james&lt;/code&gt;, and then the path continues to &lt;code&gt;coursework&lt;/code&gt;. This process of removing &lt;code&gt;.&lt;/code&gt; and resolving &lt;code&gt;..&lt;/code&gt; in a path is called &lt;strong&gt;path normalization&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Basic Linux Commands
&lt;/h2&gt;

&lt;p&gt;To effectively navigate and manage files in Linux, it is important to familiarize yourself with some basic commands. Practicing these commands is the best way to learn, so I encourage you to open your terminal, type each command, and execute it by pressing Enter. Note that lines starting with &lt;code&gt;#&lt;/code&gt; are comments, and &lt;code&gt;$&lt;/code&gt; is the shell/command prompt, which is not part of the command itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# `pwd` (print working directory) displays your current working directory.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;

&lt;span class="c"&gt;# `ls` displays all files and directories in the current working directory.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;

&lt;span class="c"&gt;# The `-a` flag lets the `ls` command print all hidden files and directories. In Linux, files and directories starting with `.` are hidden by default.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;

&lt;span class="c"&gt;# `mkdir` creates a directory if it does not exist.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;demo

&lt;span class="c"&gt;# `cd` (change directory) navigates you to the specified directory.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;demo

&lt;span class="c"&gt;# Now use the `pwd` command to check if your current working directory has been changed.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;

&lt;span class="c"&gt;# `touch` creates an empty file if it does not exist.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;demo.txt

&lt;span class="c"&gt;# Use the `ls` command to check if `demo.txt` has been created.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;

&lt;span class="c"&gt;# `rm` (remove) removes a file.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;demo.txt

&lt;span class="c"&gt;# Use the `ls` command to check if `demo.txt` has been removed.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;

&lt;span class="c"&gt;# Move one level up in the directory hierarchy.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..

&lt;span class="c"&gt;# The `-r` (recursive) flag allows the `rm` command to remove a directory and everything it contains.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take ten minutes to play around with these Linux commands in the terminal and explore how &lt;em&gt;path resolution&lt;/em&gt; and &lt;em&gt;path normalization&lt;/em&gt; work in Linux. There are some exercises at the end of this post. If you can get all those right, then your understanding of Linux paths is already solid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Command-Line Sessions and Environment Variables
&lt;/h2&gt;

&lt;p&gt;Every time you open a terminal window or a tab, a new session is created. Every session operates independently. You can check the environment variables and their values using the &lt;code&gt;env&lt;/code&gt; command. Below is an excerpt from the &lt;code&gt;env&lt;/code&gt; command output on my personal cloud server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LANG=C.UTF-8
USER=james
HOME=/home/james
PATH=/home/james/.pyenv/shims:/home/james/.local/bin:/home/linuxbrew/.linuxbrew/opt/postgresql@18/bin:/home/linuxbrew/.linuxbrew/opt/openjdk@21/bin:/home/james/.go/bin:/home/linuxbrew/.linuxbrew/opt/rustup/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/games
SHELL=/usr/bin/zsh
PWD=/home/james
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each line represents a &lt;strong&gt;key-value pair&lt;/strong&gt; (or an &lt;strong&gt;entry&lt;/strong&gt;), where both the key and value are strings. For each entry, the key is on the left-hand side of &lt;code&gt;=&lt;/code&gt;, while the value is on the right-hand side. To display the value associated with a specific key, use the command &lt;code&gt;echo $&amp;lt;key&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt;
james
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
/home/james
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may sometimes see a tilde (&lt;code&gt;~&lt;/code&gt;) in a path. Before passing the path to a program, the shell expands &lt;code&gt;~&lt;/code&gt; to the user's home directory using the value of the &lt;code&gt;HOME&lt;/code&gt; variable. For example, in this case, &lt;code&gt;~/project&lt;/code&gt; is expanded to &lt;code&gt;/home/james/project&lt;/code&gt; before being passed along. Because a user's home directory is always an absolute path, a &lt;code&gt;~&lt;/code&gt;-prefixed path becomes an absolute path after expansion. Note that this expansion is a shell feature, not an OS feature — programs that read a path from a config file or other input do not expand &lt;code&gt;~&lt;/code&gt; on their own.&lt;/p&gt;

&lt;p&gt;The operating system and applications use these environment variables throughout their lifecycles. For example, when you change to another directory, the &lt;code&gt;PWD&lt;/code&gt; environment variable is changed accordingly. The &lt;code&gt;pwd&lt;/code&gt; command just displays the value of &lt;code&gt;PWD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The value of the &lt;code&gt;PATH&lt;/code&gt; variable is long and scary, but upon a closer look, you may notice that it is a set of absolute paths separated by a colon (&lt;code&gt;:&lt;/code&gt;). We can use the &lt;code&gt;echo $PATH | tr : '\n'&lt;/code&gt; command to make the output easier to read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/home/james/.pyenv/shims
/home/james/.local/bin
/home/linuxbrew/.linuxbrew/opt/postgresql@18/bin
/home/linuxbrew/.linuxbrew/opt/openjdk@21/bin
/home/james/.go/bin
/home/linuxbrew/.linuxbrew/opt/rustup/bin
/home/linuxbrew/.linuxbrew/bin
/home/linuxbrew/.linuxbrew/sbin
/usr/local/bin
/usr/bin
/bin
/usr/games
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;echo $PATH&lt;/code&gt; outputs the value of &lt;code&gt;PATH&lt;/code&gt;, and &lt;code&gt;|&lt;/code&gt; pipes the output to &lt;code&gt;tr : '\n'&lt;/code&gt;, which replaces all colons with newline characters (&lt;code&gt;\n&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;You can set a new environment variable using the &lt;code&gt;export&lt;/code&gt; command. If the key already exists, the new value will override the previous one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TEST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"test"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$TEST&lt;/span&gt;
&lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To prepend an absolute path to the &lt;code&gt;PATH&lt;/code&gt; variable, a conventional approach is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/my/path:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, a new string is created by concatenating &lt;code&gt;/my/path:&lt;/code&gt; and the current value of &lt;code&gt;PATH&lt;/code&gt;. This new value then replaces the original &lt;code&gt;PATH&lt;/code&gt;. Many installation guides ask you to "add X to the PATH," where X is an absolute path. They are referring to this process.&lt;/p&gt;

&lt;p&gt;Each session has its own set of environment variables. This means if you set a variable in one session, it won't affect any other sessions. Additionally, if you close the terminal and reopen it, any changes to environment variables will be lost. To ensure that certain environment variables are set automatically every time you start a new session, add the &lt;code&gt;export&lt;/code&gt; commands to your &lt;strong&gt;shell configuration file&lt;/strong&gt;, which is another big topic. But for now, you just need to know this: if your shell interpreter is &lt;code&gt;bash&lt;/code&gt;, then your shell configuration file is &lt;code&gt;.bashrc&lt;/code&gt;; if your shell interpreter is &lt;code&gt;zsh&lt;/code&gt;, then your shell configuration file is &lt;code&gt;.zshrc&lt;/code&gt;. Use the &lt;code&gt;echo $SHELL&lt;/code&gt; command to check which shell interpreter you are using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paths to Executables
&lt;/h2&gt;

&lt;p&gt;In Linux, an &lt;strong&gt;executable&lt;/strong&gt; is a file that the operating system can run as a program. It can be a &lt;strong&gt;compiled binary&lt;/strong&gt; or a &lt;strong&gt;script&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When we execute a command, the operating system looks for an executable with the same name and runs it. But where are these executables located? For example, if I can run &lt;code&gt;python&lt;/code&gt; in the current environment, then where is &lt;code&gt;python&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;You can check the absolute path of the &lt;code&gt;python&lt;/code&gt; that the operating system is using with the &lt;code&gt;which python&lt;/code&gt; command. In my environment, I get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/home/james/.pyenv/shims/python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may have already noticed that &lt;code&gt;/home/james/.pyenv/shims&lt;/code&gt; appears in the &lt;code&gt;PATH&lt;/code&gt; variable. It turns out that when we run a command, the shell iterates over all the directories listed in the &lt;code&gt;PATH&lt;/code&gt; variable, concatenates each directory path with the command name, and checks whether the resulting file exists. If the command file exists, the shell executes it immediately. If no such file is found after checking all the directories, it displays a message indicating that the command was not found.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;which&lt;/code&gt; alone returns only the first match. To display all the locations of executable files, pass a &lt;code&gt;-a&lt;/code&gt; flag to the &lt;code&gt;which&lt;/code&gt; command. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ which -a ls
/usr/bin/ls
/bin/ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although there are two candidates for &lt;code&gt;ls&lt;/code&gt; in the system, Linux always runs the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paths in IDEs
&lt;/h2&gt;

&lt;p&gt;If you use VSCode, PyCharm, Cursor, or other graphical IDEs, you usually can run a Python script by clicking a button. Many people don't know what happens behind the scenes, and when they come across a "File Not Found" error, they're often at a loss.&lt;/p&gt;

&lt;p&gt;In fact, when you click the button, the IDE runs a command in the background and then displays the output directly. Depending on the IDE you use and the configuration you set up, the current working directory that the IDE uses to run the script may be the project root directory or the directory where the script resides.&lt;/p&gt;

&lt;p&gt;When we encounter a "File Not Found" issue, we can always troubleshoot it by printing the current working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getcwd&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we manually resolve the relative paths in the Python script and check whether the absolute paths exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compiler/Interpreter Paths
&lt;/h2&gt;

&lt;p&gt;In addition to &lt;code&gt;PATH&lt;/code&gt;, many compilers and interpreters rely on specific environment variables to locate related files. For instance, &lt;code&gt;g++&lt;/code&gt; uses &lt;code&gt;CPATH&lt;/code&gt; to find header files (e.g., &lt;code&gt;.hpp&lt;/code&gt;) and &lt;code&gt;LIBRARY_PATH&lt;/code&gt; to find compiled library files (e.g., &lt;code&gt;.a&lt;/code&gt;, &lt;code&gt;.so&lt;/code&gt;, &lt;code&gt;.dylib&lt;/code&gt;). If you're using Homebrew to install C++ libraries, you’ll need to set these variables in your shell configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CPATH&lt;/span&gt;&lt;span class="s2"&gt;:/opt/homebrew/include"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LIBRARY_PATH&lt;/span&gt;&lt;span class="s2"&gt;:/opt/homebrew/lib"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;/opt/homebrew&lt;/code&gt; is the default Homebrew root directory on macOS with Apple Silicon, but it may vary depending on your operating system or installation setup. Adding these paths ensures that &lt;code&gt;g++&lt;/code&gt; can find your Homebrew-installed libraries automatically.&lt;/p&gt;

&lt;p&gt;Another example is the Python interpreter. It uses the value of the &lt;code&gt;PYTHONPATH&lt;/code&gt; environment variable to locate modules and packages when you use &lt;code&gt;import&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's do an experiment. First, we set a value for &lt;code&gt;PYTHONPATH&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/my/package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the following Python script in the same session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see &lt;code&gt;/my/package&lt;/code&gt; in the output list. We can add custom local packages to the Python environment using this approach, which is quite common in Python projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exercises
&lt;/h2&gt;

&lt;p&gt;1. Which of the following is NOT an absolute path?&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a. &lt;code&gt;/etc/passwd&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b. &lt;code&gt;./home/james&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c. &lt;code&gt;~/demo&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d. &lt;code&gt;/root/../home/alice&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2. Which of the following is NOT a relative path?&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a. &lt;code&gt;..&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b. &lt;code&gt;../alice/demo&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c. &lt;code&gt;/.ssh/id_rsa&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d. &lt;code&gt;bob/notes/linux&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3. Which of the following path resolutions are NOT correct? Select all that apply.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a. &lt;code&gt;/home/james&lt;/code&gt; + &lt;code&gt;notes&lt;/code&gt; → &lt;code&gt;/home/jamesnotes&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b. &lt;code&gt;/etc/nginx&lt;/code&gt; + &lt;code&gt;./conf.d&lt;/code&gt; → &lt;code&gt;/etc/nginx/./conf.d&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c. &lt;code&gt;/usr/bin/&lt;/code&gt; + &lt;code&gt;mkdir&lt;/code&gt; → &lt;code&gt;/usr/bin/mkdir&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d. &lt;code&gt;/home/bob/demo&lt;/code&gt; + &lt;code&gt;../coursework&lt;/code&gt; → &lt;code&gt;/home/bob/demo/coursework&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4. Which of the following path normalizations are correct? Select all that apply.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a. &lt;code&gt;/home/alice/notes/../demo&lt;/code&gt; → &lt;code&gt;/home/alice/notes/demo&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b. &lt;code&gt;/usr/bin/./touch&lt;/code&gt; → &lt;code&gt;/usr/bin/touch&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c. &lt;code&gt;/home/james/./resume&lt;/code&gt; → &lt;code&gt;home/james/resume&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d. &lt;code&gt;/home/alice/./../bob/resume&lt;/code&gt; → &lt;code&gt;/home/bob/resume&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;5. Chris is currently in the &lt;code&gt;/home/chris/coursework&lt;/code&gt; directory and he runs &lt;code&gt;cd src/hw1&lt;/code&gt;. Which of the following outcomes are possible? Select all that apply.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a. Chris is navigated to &lt;code&gt;/src/hw1&lt;/code&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b. An error message is displayed, and Chris stays in the &lt;code&gt;/home/chris/coursework&lt;/code&gt; directory.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c. Chris is navigated to &lt;code&gt;/home/chris/coursework/src/hw1&lt;/code&gt;.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d. An error message is displayed, and Chris is navigated to &lt;code&gt;/src/hw1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;6. Bob has trouble navigating to &lt;code&gt;/home/bob/project/src/main&lt;/code&gt;. His terminal session is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/bob
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;project/src
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;main
&lt;span class="nb"&gt;cd&lt;/span&gt;: no such file or directory: main
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls
test &lt;/span&gt;Main.java build.gradle.kts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which of the following statements are correct? Select all that apply.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a. There is no directory named &lt;code&gt;main&lt;/code&gt; in &lt;code&gt;/home/bob/project/src&lt;/code&gt;.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b. When Bob runs the &lt;code&gt;cd main&lt;/code&gt; command, he stays in the &lt;code&gt;/home/bob&lt;/code&gt; directory.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c. There are three files or directories in &lt;code&gt;/home/bob/project/src&lt;/code&gt;.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d. The &lt;code&gt;cd main&lt;/code&gt; command creates a &lt;code&gt;main&lt;/code&gt; directory in &lt;code&gt;/home/bob/project/src&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;7. Alice adds the following command to her shell configuration file &lt;code&gt;.bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;:/home/alice/bin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;She then checks with &lt;code&gt;echo $PATH&lt;/code&gt; and finds that &lt;code&gt;/home/alice/bin&lt;/code&gt; has been added to &lt;code&gt;PATH&lt;/code&gt;. There is a &lt;code&gt;ls&lt;/code&gt; executable in &lt;code&gt;/home/alice/bin&lt;/code&gt;. However, when she runs &lt;code&gt;ls&lt;/code&gt;, the &lt;code&gt;/home/alice/bin/ls&lt;/code&gt; is not executed. Which of the following statements are correct? Select all that apply.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a. She can check all &lt;code&gt;ls&lt;/code&gt; executables in the environment using &lt;code&gt;which -a ls&lt;/code&gt;.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b. If she changes the &lt;code&gt;export&lt;/code&gt; statement to &lt;code&gt;export PATH="/home/alice/bin:$PATH"&lt;/code&gt; and moves it to the end of the shell configuration file, &lt;code&gt;/home/alice/bin/ls&lt;/code&gt; may be executed when she runs &lt;code&gt;ls&lt;/code&gt;.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c. &lt;code&gt;/home/alice/bin/ls&lt;/code&gt; was not executed because she is in a wrong working directory.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d. Because she is not using &lt;code&gt;bash&lt;/code&gt; as a shell interpreter, adding the &lt;code&gt;export&lt;/code&gt; statement to &lt;code&gt;.bashrc&lt;/code&gt; doesn't take effect.&lt;/p&gt;

&lt;p&gt;8. James is using a niche IDE, and he runs the following script by clicking the "run" button in the user interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/raw_data.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;# Read all content from the file and print it out
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The path of this file is &lt;code&gt;src/test/file.py&lt;/code&gt;, relative to the project root directory. He wants to read the content from &lt;code&gt;data/raw_data.txt&lt;/code&gt;, relative to the project root directory. However, after running this script, he gets a &lt;code&gt;FileNotFoundError&lt;/code&gt;. He then checks the current working directory by adding the following at the beginning of the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getcwd&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The terminal outputs &lt;code&gt;/home/james/project/src/test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What should the value of &lt;code&gt;filename&lt;/code&gt; be to make the script work?&lt;/p&gt;

&lt;h2&gt;
  
  
  Answer Key
&lt;/h2&gt;

&lt;p&gt;&lt;/p&gt;
  Answer Key
  &lt;ol&gt;
&lt;li&gt;b&lt;/li&gt;
&lt;li&gt;c&lt;/li&gt;
&lt;li&gt;ad&lt;/li&gt;
&lt;li&gt;bd&lt;/li&gt;
&lt;li&gt;bc&lt;/li&gt;
&lt;li&gt;ac&lt;/li&gt;
&lt;li&gt;ab&lt;/li&gt;
&lt;li&gt;&lt;code&gt;../../data/raw_data.txt&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
