<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Practical Skills | Haobin Tan</title><link>https://haobin-tan.netlify.app/tags/practical-skills/</link><atom:link href="https://haobin-tan.netlify.app/tags/practical-skills/index.xml" rel="self" type="application/rss+xml"/><description>Practical Skills</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Sat, 11 Mar 2023 00:00:00 +0000</lastBuildDate><image><url>https://haobin-tan.netlify.app/media/icon_hu7d15bc7db65c8eaf7a4f66f5447d0b42_15095_512x512_fill_lanczos_center_3.png</url><title>Practical Skills</title><link>https://haobin-tan.netlify.app/tags/practical-skills/</link></image><item><title>Shell</title><link>https://haobin-tan.netlify.app/docs/cs/practical-skills/01_shell/</link><pubDate>Sat, 11 Mar 2023 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/cs/practical-skills/01_shell/</guid><description>&lt;p>TL;DR&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Shell is a programming environement. It has variables, conditionals, loops, and functions.&lt;/p>
&lt;ul>
&lt;li>When shell is askedt o execute a command, it search the required program in &lt;code>$PATH&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>There are two types of paths: absolute and relative.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Default input and output of program executed in shell are both terminal (i.e., keyboard as input and screen as output).&lt;/p>
&lt;ul>
&lt;li>We can redirect the input and output streams using with &lt;code>&amp;lt; file&lt;/code> (input from file), &lt;code>&amp;gt; file&lt;/code> (output to file and rewrite it), and &lt;code>&amp;gt;&amp;gt; file&lt;/code> (output to file and append at the end).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Roo user is a powerful tool.&lt;/p>
&lt;ul>
&lt;li>Use the &lt;code>sudo&lt;/code> command.&lt;/li>
&lt;li>But double check that you really wanted to use it!&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="using-the-shell">Using the shell&lt;/h2>
&lt;p>When you launch your terminal, you will see a &lt;em>&lt;strong>prompt&lt;/strong>&lt;/em> that often looks a little like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>You are on the machine called &lt;code>missing&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Your “current working directory”, or where you currently are, is &lt;code>~&lt;/code> (short for “home”)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The &lt;code>$&lt;/code> tells you that you are not the root user&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>At this prompt you can type a &lt;em>command&lt;/em>, which will then be interpreted by the shell.&lt;/p>
&lt;h3 id="example">Example&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$ date
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Fri &lt;span class="m">10&lt;/span> Jan &lt;span class="m">2020&lt;/span> 11:49:31 AM EST
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Here, we executed the &lt;code>date&lt;/code> program, which (perhaps unsurprisingly) prints the current date and time. The shell then asks us for another command to execute.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$ &lt;span class="nb">echo&lt;/span> hello
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hello
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We told the shell to execute the program &lt;code>echo&lt;/code> with the argument &lt;code>hello&lt;/code>.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The &lt;code>echo&lt;/code> program simply prints out its arguments.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The shell parses the command by splitting it by whitespace, and then runs the program indicated by the first word, supplying each subsequent word as an argument that the program can access.&lt;/p>
&lt;ul>
&lt;li>If you want to provide an argument that contains spaces or other special characters (e.g. &amp;ldquo;Hello world&amp;rdquo;), you can either quote the argument with &lt;code>'&lt;/code> or &lt;code>&amp;quot;&lt;/code> (&lt;code>&amp;quot;Hello world&amp;quot;&lt;/code>), or escape just the relevant characters with &lt;code>\&lt;/code> (&lt;code>Hello\ world&lt;/code>)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="under-the-hood">Under the hood&lt;/h3>
&lt;p>&lt;strong>The shell is a programming environment&lt;/strong>, just like Python or Ruby.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>It has variables, conditionals, loops, and functions.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>When you run commands in your shell, you are really writing a small bit of code that your shell interprets.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If the shell is asked to execute a command that doesn’t match one of its programming keywords, it consults an &lt;em>environment variable&lt;/em> called &lt;code>$PATH&lt;/code> that lists which directories the shell should search for programs when it is given a command&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$ &lt;span class="nb">echo&lt;/span> &lt;span class="nv">$PATH&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ which &lt;span class="nb">echo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/bin/echo
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ /bin/echo &lt;span class="nv">$PATH&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>When we run the &lt;code>echo&lt;/code> command,&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The shell sees that it should execute the program &lt;code>echo&lt;/code>, and then searches &lt;strong>through the &lt;code>:&lt;/code>-separated list of directories in &lt;code>$PATH&lt;/code>&lt;/strong> for a file by that name.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>When it finds it, it runs it (assuming the file is &lt;em>executable&lt;/em>)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>We can find out which file is executed for a given program name using the &lt;code>which&lt;/code> program.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>We can also bypass &lt;code>$PATH&lt;/code> entirely by giving the &lt;em>path&lt;/em> to the file we want to execute.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="navigating-in-the-shell">Navigating in the shell&lt;/h2>
&lt;p>A path on the shell is a delimited list of directories; separated by &lt;code>/&lt;/code> on Linux and macOS and &lt;code>\&lt;/code> on Windows.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>On Linux and macOS, the path &lt;code>/&lt;/code> is the “root” of the file system, under which all directories and files lie.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>on Windows there is one root for each disk partition (e.g., &lt;code>C:\&lt;/code>).&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>In the following, it is assumed that a Linux filesystem is being used.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Absolute path&lt;/strong>: A path that starts with &lt;code>/&lt;/code>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Relative path&lt;/strong>: Relative to the current working directory&lt;/p>
&lt;ul>
&lt;li>
&lt;p>We can see with the &lt;code>pwd&lt;/code> command and&lt;/p>
&lt;/li>
&lt;li>
&lt;p>change with the &lt;code>cd&lt;/code> command&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>In a path, &lt;/p>
&lt;ul>
&lt;li>&lt;code>.&lt;/code> : the current directory&lt;/li>
&lt;li> &lt;code>..&lt;/code>: its parent directory&lt;/li>
&lt;li>&lt;code>~&lt;/code>: the &lt;code>$HOME&lt;/code> directory&lt;/li>
&lt;li>&lt;code>cd -&lt;/code> : &lt;code>cd&lt;/code> to the directory you&amp;rsquo;re previously in&lt;/li>
&lt;/ul>
&lt;p>Example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$ &lt;span class="nb">pwd&lt;/span> &lt;span class="c1"># print working directory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/home/missing
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ &lt;span class="nb">cd&lt;/span> /home
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:/home$ &lt;span class="nb">pwd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/home
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:/home$ &lt;span class="nb">cd&lt;/span> ..
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:/$ &lt;span class="nb">pwd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:/$ &lt;span class="nb">cd&lt;/span> ./home
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:/home$ &lt;span class="nb">pwd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/home
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:/home$ &lt;span class="nb">cd&lt;/span> missing
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ &lt;span class="nb">pwd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/home/missing
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ ../../bin/echo hello
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hello
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Notice that our shell prompt kept us informed about what our current working directory was. You can configure your prompt to show you all sorts of useful information&lt;/p>
&lt;/blockquote>
&lt;p>In general, when we run a program, it will operate &lt;strong>in the current directory unless we tell it otherwise&lt;/strong>.&lt;/p>
&lt;p>To see what lives in a given directory, we use the &lt;code>ls&lt;/code> command.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Unless a directory is given as its first argument, &lt;code>ls&lt;/code> will print the contents of the current directory.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$ ls -l /home
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">drwxr-xr-x &lt;span class="m">1&lt;/span> missing users &lt;span class="m">4096&lt;/span> Jun &lt;span class="m">15&lt;/span> &lt;span class="m">2019&lt;/span> missing
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>The &lt;code>d&lt;/code> at the beginning of the line tells us that &lt;code>missing&lt;/code> is a directory.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The following three groups of characters (&lt;code>rwx&lt;/code>) indicate permissions (&lt;code>r&lt;/code>-read, &lt;code>w&lt;/code>-write, &lt;code>x&lt;/code>-execute) of&lt;/p>
&lt;ul>
&lt;li>
&lt;p>the owner of the file (&lt;code>missing&lt;/code>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>the owning group (&lt;code>users&lt;/code>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>everyone else&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Permissions&lt;/p>
&lt;ul>
&lt;li>
&lt;p>A &lt;code>-&lt;/code> indicates that the given principal does not have the given permission&lt;/p>
&lt;ul>
&lt;li>Above, only the owner (with permission &lt;code>rwx&lt;/code>) is allowed to modify (&lt;code>w&lt;/code>) the &lt;code>missing&lt;/code> directory (i.e., add/remove files in it).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>To enter a directory, a user must have “search” (represented by “execute”: &lt;code>x&lt;/code>) permissions on that directory (and its parents).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>To list its contents, a user must have read (&lt;code>r&lt;/code>) permissions on that directory.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;div class="flex px-4 py-3 mb-6 rounded-md bg-primary-100 dark:bg-primary-900">
&lt;span class="pr-3 pt-1 text-primary-600 dark:text-primary-300">
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m11.25 11.25l.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0a9 9 0 0 1 18 0m-9-3.75h.008v.008H12z"/>&lt;/svg>
&lt;/span>
&lt;span class="dark:text-neutral-300">&lt;p>If you ever want &lt;em>more&lt;/em> information about a program’s arguments, inputs, outputs, or how it works in general, give the &lt;code>man&lt;/code> program a try.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>It takes as an argument the name of a program, and shows you its &lt;em>manual page&lt;/em>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Press &lt;code>q&lt;/code> to exit.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/span>
&lt;/div>
&lt;h2 id="connecting-programs">Connecting programs&lt;/h2>
&lt;p>In the shell, programs have two primary “streams” associated with them: their &lt;strong>input stream&lt;/strong> and their &lt;strong>output stream&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>When the program tries to read input, it reads from the input stream.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>When it prints something, it prints to its output stream.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Normally, a program’s input and output are both your terminal. That is, your keyboard as input and your screen as output.&lt;/strong>&lt;/p>
&lt;p>We can also rewire those streams. The simplest form of redirection is&lt;/p>
&lt;ul>
&lt;li>&lt;code>&amp;lt; file&lt;/code>: rewire the input of this program to be the content of &lt;code>file&lt;/code> &lt;/li>
&lt;li> &lt;code>&amp;gt; file&lt;/code>: rewire the output of the preceding programi into this file&lt;/li>
&lt;/ul>
&lt;p>(more see &lt;a href="https://www.educative.io/answers/how-to-do-input-output-redirection-in-linux">How to do input/output redirection in Linux&lt;/a>). These let you rewire the input and output streams of a program to a file respectively.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$ &lt;span class="nb">echo&lt;/span> hello &amp;gt; hello.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ cat hello.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hello
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ cat &amp;lt; hello.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hello
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Read content from hello.txt and output to hello2.txt&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ cat &amp;lt; hello.txt &amp;gt; hello2.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">missing:~$ cat hello2.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hello
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>cat&lt;/code> is a program that con&lt;code>cat&lt;/code>enates files.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>When given file names as arguments, it prints the contents of each of the files in sequence to its output stream&lt;/p>
&lt;/li>
&lt;li>
&lt;p>But when &lt;code>cat&lt;/code> is not given any arguments, it prints contents from its input stream to its output stream (like in the third example above).&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Note that &lt;code>&amp;gt;&lt;/code> will overwrite the target file. If you want to append instead, use &lt;code>&amp;gt;&amp;gt;&lt;/code>.&lt;/p>
&lt;p>Where this kind of input/output redirection really shines is in the use of &lt;em>&lt;strong>pipes&lt;/strong>&lt;/em>: &lt;strong>The &lt;code>|&lt;/code> operator lets you “chain” programs such that the output of one is the input of another&lt;/strong>. The &lt;code>|&lt;/code> operator takes the output of the program to the left and make it the input of the program to the right.&lt;/p>
&lt;p>E.g.: When you use &lt;code>cat&lt;/code> command to view a file which spans multiple pages, the prompt quickly jumps to the last page of the file, and you do not see the content in the middle. To avoid this, you can pipe the output of the &lt;code>cat&lt;/code> command to &lt;code>less&lt;/code> which will show you only one scroll length of content at a time (&lt;a href="https://www.guru99.com/linux-pipe-grep.html#:~:text=is%20a%20Filter%3F-,What%20is%20a%20Pipe%20in%20Linux%3F,'%7C'%20denotes%20a%20pipe.">Pipe, Grep and Sort Command in Linux/Unix with Examples&lt;/a>).&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">missing:~$ cat hello2.txt &lt;span class="p">|&lt;/span> less
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="a-versatile-and-powerful-tool">A versatile and powerful tool&lt;/h2>
&lt;p>On most Unix-like systems, one user is special: &lt;strong>the “root” user&lt;/strong>.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The root user is above (almost) all access restrictions, and can create, read, update, and delete any file in the system.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>You will not usually log into your system as the root user though, since it’s too easy to accidentally break something.&lt;/p>
&lt;ul>
&lt;li>Instead, you will be using the &lt;code>sudo&lt;/code> command. As its name implies, it lets you “do” something “as su” (short for “super user”, or “root”).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>When you get permission denied errors, it is usually because you need to do something as root. Though make sure you first double-check that you really wanted to do it that way!!!&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="reference">Reference&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://missing.csail.mit.edu/2020/course-shell/">Course overview + the shell&lt;/a>&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Z56Jmr9Z34Q?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"
>&lt;/iframe>
&lt;/div>
&lt;/li>
&lt;/ul></description></item><item><title>Practical Skills</title><link>https://haobin-tan.netlify.app/docs/cs/practical-skills/</link><pubDate>Sat, 04 Mar 2023 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/cs/practical-skills/</guid><description>&lt;p>The notes are based on the course &lt;strong>&lt;a href="https://missing.csail.mit.edu/">&amp;ldquo;The Missing Semester of Your CS Education&amp;rdquo;&lt;/a>&lt;/strong>.&lt;/p></description></item></channel></rss>