<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="/assets/xsl/rss.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<id>https://tty1.blog</id>
	<link href="https://tty1.blog" rel="alternate" />
	<title>tty1</title>
	<subtitle>I&#39;m afraid it&#39;s terminal</subtitle>
	<rights>© Benjamin Hollon (guest articles © their respective authors). All articles usable under CC BY-SA 4.0 International.</rights>
	<language>en-US</language>
	
	<entry>
		<id>https://tty1.blog/articles/real-world-solutions-updating-ebooks/</id>
		<link href="https://tty1.blog/articles/real-world-solutions-updating-ebooks/" rel="alternate"/>
		<title>Real World Solutions: Updating Ebooks</title>
		<author>
			<name></name>
		</author>
		<summary>So far, this blog has largely been tutorials on how to use particular commands or workflows. I&#39;ll keep doing that, but I also want to highlight some real-world problems that can easily be solved with some knowledge of shell scripting and the command line.

To start off, here&#39;s how I used the `find` command to create a script for [Nantucket E-Books](https://nantucketebooks.com) to help them easily update the code for all of their books at once.</summary>
		<content type="html">&lt;p&gt;So far, this blog has largely been tutorials on how to use particular commands or workflows. I&#39;ll keep doing that, but I also want to highlight some real-world problems that can easily be solved with some knowledge of shell scripting and the command line.&lt;/p&gt;
&lt;p&gt;To start off, here&#39;s how I used the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;/code&gt; command to create a script for &lt;a href=&quot;https://nantucketebooks.com/&quot;&gt;Nantucket E-Books&lt;/a&gt; to help them easily update the code for all of their books at once.&lt;/p&gt;
&lt;h2 id=&quot;the-setup&quot; tabindex=&quot;-1&quot;&gt;The Setup&lt;/h2&gt;
&lt;p&gt;While I didn&#39;t have the exact file structure to work from, based on &lt;a href=&quot;https://www.ndhfilms.com/&quot;&gt;Nicholas&lt;/a&gt;&#39;s description I was able to infer that it looked something like this:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
├── author1
│   ├── book1
│   │   └── assets
│   │       └── js
│   └── book2
│       └── assets
│           └── js
├── author2
│   └── book1
│       └── assets
│           └── js
├── author3
│   ├── book1
│   │   └── assets
│   │       └── js
│   ├── book2
│   │   └── assets
│   │       └── js
│   └── book3
│       └── assets
│           └── js
├── author4
│   ├── book1
│   │   └── assets
│   │       └── js
│   └── book2
│       └── assets
│           └── js
└── author5
    ├── book1
    │   └── assets
    │       └── js
    ├── book2
    │   └── assets
    │       └── js
    ├── book3
    │   └── assets
    │       └── js
    └── book4
        └── assets
            └── js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Within each book&#39;s folder, the same three JavaScript files needed to be updated to the newest version.&lt;/p&gt;
&lt;h2 id=&quot;the-solution&quot; tabindex=&quot;-1&quot;&gt;the solution&lt;/h2&gt;
&lt;p&gt;My solution was a simple shell script:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;subdirs&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$PWD&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-mindepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-maxdepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; d&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Get the full paths of all second-level subdirectories&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$subdirs&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; subdir&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# for each selected subdirectory, do the following&lt;/span&gt;
	&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$subdir&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# moves into the correct directory&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;# do your actions here&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This solution let him add the actual commands to copy the new files at the indicated location, but would make sure whatever he put there would be executed in every book&#39;s folder. For example:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; ~/code/updated-file.js ./assets/js/file.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above would take the updated file and copy it to the location it belongs in each book&#39;s subdirectory.&lt;/p&gt;
&lt;h2 id=&quot;breaking-it-down&quot; tabindex=&quot;-1&quot;&gt;breaking it down&lt;/h2&gt;
&lt;p&gt;Let&#39;s break this solution down a little.&lt;/p&gt;
&lt;p&gt;To start off, I wanted to get every book&#39;s path and store it to a variable, &lt;code class=&quot;language-bash&quot;&gt;subdirs&lt;/code&gt;. The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;/code&gt; command is ideal for that purpose.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the positional &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$PWD&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt; argument specifies the containing directory to search within (&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$PWD&lt;/span&gt;&lt;/code&gt; is a variable that returns the current working directory). You could set this to the path of your parent directory if you like, to be able to run the script from anywhere, but I didn&#39;t know that path and figured running the command from the directory would suffice.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; d&lt;/code&gt; limits results to directories only; by default, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;/code&gt; looks for both files and directories (&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; f&lt;/code&gt; would find files only)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-mindepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt; makes sure results are at least two directories away from the base directory&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-maxdepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt; makes sure results are a maximum of two directories away from the base directory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Combined, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-mindepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-maxdepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt; essentially just say &amp;quot;find all results that are exactly two subdirectories away&amp;quot;. In our case, this perfectly matches all book directories, since they&#39;re subdirectories of the author directories, but &lt;em&gt;keeps&lt;/em&gt; the script from matching the &lt;code class=&quot;language-bash&quot;&gt;assets&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;js&lt;/code&gt; directories, since those are more than two subdirectories away.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;/code&gt; has tons more great options, I highly recommend you checking them out via &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Let&#39;s test it:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;/tmp/tmp.UkyqnYccbh&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;subdirs&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$PWD&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-mindepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-maxdepth&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt; d&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
/tmp/tmp.UkyqnYccbh&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$subdirs&lt;/span&gt;&quot;&lt;/span&gt;
/tmp/tmp.UkyqnYccbh/author2/book1
/tmp/tmp.UkyqnYccbh/author4/book2
/tmp/tmp.UkyqnYccbh/author4/book1
/tmp/tmp.UkyqnYccbh/author1/book2
/tmp/tmp.UkyqnYccbh/author1/book1
/tmp/tmp.UkyqnYccbh/author3/book2
/tmp/tmp.UkyqnYccbh/author3/book1
/tmp/tmp.UkyqnYccbh/author3/book3
/tmp/tmp.UkyqnYccbh/author5/book4
/tmp/tmp.UkyqnYccbh/author5/book2
/tmp/tmp.UkyqnYccbh/author5/book1
/tmp/tmp.UkyqnYccbh/author5/book3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is, indeed, all of the exact directories we want!&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;I run my test commands for these articles within a temporary directory, in this case &lt;code class=&quot;language-bash&quot;&gt;/tmp/tmp.UkyqnYccbh&lt;/code&gt;, so that they don&#39;t interfere with the rest of my system. I use this shell alias to quickly create and enter a temporary directory when I run &lt;code class=&quot;language-bash&quot;&gt;tempdir&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;tempdir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cd &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;mktemp &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/aside&gt;
&lt;p&gt;Next, we want to loop through all of these folders. In &lt;a href=&quot;https://tty1.blog/articles/moosh-the-moo-shell/&quot;&gt;my last article&lt;/a&gt;, I mentioned the strategy of piping a list to a while loop, which I&#39;ve done again here.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$subdirs&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; subdir&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;# …&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An important note is that pipes like this create &lt;em&gt;subshells&lt;/em&gt;, meaning that any variables I set within the loop cannot affect the rest of the script. For this use case, that doesn&#39;t matter (since created files/directories will of course remain after the subshell finishes), but it&#39;s good to be aware of when adapting this script to your own purposes.&lt;/p&gt;
&lt;p&gt;Now that we are in the loop, we&#39;ll move into the subdirectory that&#39;s currently being processed:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$subdir&lt;/span&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Easy peasy. As we mentioned, anything else we want done while in this folder can now be added.&lt;/p&gt;
&lt;h2 id=&quot;the-results&quot; tabindex=&quot;-1&quot;&gt;the results&lt;/h2&gt;
&lt;p&gt;Nicholas&#39;s immediate response?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I just updated the software and stylesheets for forty-eight e-books on the site with one command.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He&#39;s written &lt;a href=&quot;https://nantucketebooks.com/blog/2023/11/2023-11-05_version_4.1_of_nantucket_e-books_released.html&quot;&gt;a blog post of his own&lt;/a&gt; that mentions this solution, which is also worth reading. And while you&#39;re there, check out &lt;a href=&quot;https://nantucketebooks.com/&quot;&gt;the platform&lt;/a&gt;, it&#39;s a great and easily accessible platform to read books for free from any device, with built-in audiobooks. It&#39;s a great project, and I&#39;m proud to have been able to lighten the load of keeping it running.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;conclusion&lt;/h2&gt;
&lt;p&gt;I&#39;ll leave off there. If you have solutions to real-world problems of your own to continue this series &lt;em&gt;or&lt;/em&gt; a real-world problem you need help solving with the shell, I&#39;d love if you&#39;d send me a message! It can be like this article, where I wrote about a solution to someone else&#39;s problem, or you can write a guest article for publication on this blog.&lt;/p&gt;
&lt;p&gt;My email (and PGP key!) are below, I&#39;d love to talk through your ideas with you. See you next time!&lt;/p&gt;</content>
		<updated>2024-02-10T22:40:54.000Z</updated>
		<published>2024-02-10T22:40:54.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/moosh-the-moo-shell/</id>
		<link href="https://tty1.blog/articles/moosh-the-moo-shell/" rel="alternate"/>
		<title>moosh: the Moo Shell</title>
		<author>
			<name></name>
		</author>
		<summary>As a joke, this week I coded a Linux shell: `moosh`. The whole idea behind `moosh` is that it responds to every command with a random-length &quot;MooOooOOo…&quot;

So, yes, it&#39;s a joke. But let&#39;s take a look at it and see if there are any ideas about scripting we can learn along the way.</summary>
		<content type="html">&lt;p&gt;As a joke, this week I coded a Linux shell: &lt;code class=&quot;language-bash&quot;&gt;moosh&lt;/code&gt;. The whole idea behind &lt;code class=&quot;language-bash&quot;&gt;moosh&lt;/code&gt; is that it responds to every command with a random-length &amp;quot;MooOooOOo…&amp;quot;&lt;/p&gt;
&lt;p&gt;So, yes, it&#39;s a joke. But let&#39;s take a look at it and see if there are any ideas about scripting we can learn along the way.&lt;/p&gt;
&lt;h2 id=&quot;the-code&quot; tabindex=&quot;-1&quot;&gt;The Code&lt;/h2&gt;
&lt;p&gt;The code is pretty short, written in &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;, so here is the full code:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$ &quot;&lt;/span&gt;
	&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; input
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$input&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mo&quot;&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
				&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;o&quot;&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
				&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;O&quot;&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;…&quot;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&#39;ll break this down, piece by piece.&lt;/p&gt;
&lt;h2 id=&quot;part-1%3A-the-shebang&quot; tabindex=&quot;-1&quot;&gt;Part 1: The Shebang&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first line of all shell scripts follows this form. Called the &lt;code class=&quot;language-bash&quot;&gt;shebang&lt;/code&gt;, it tells your system what program to use to run the file. In this case we want to use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;, but we don&#39;t have a guarantee that the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt; executable will be in the same location, so pointing to a location like &lt;code class=&quot;language-bash&quot;&gt;/bin/bash&lt;/code&gt; might not work on all systems.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;For example, on my current Linux distribution, NixOS, packages are stored in odd places and &lt;code class=&quot;language-bash&quot;&gt;/bin/bash&lt;/code&gt; does not exist.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;To solve this dilemma, we can use &lt;code class=&quot;language-bash&quot;&gt;/usr/bin/env&lt;/code&gt; to find the location of any executable. Another common use is to create a python script; to do so, you could use this &lt;code class=&quot;language-bash&quot;&gt;shebang&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before we move on, I should also cover &lt;code class=&quot;language-bash&quot;&gt;/bin/sh&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On a Linux (or similar) system, &lt;code class=&quot;language-bash&quot;&gt;/bin/sh&lt;/code&gt; will point to a POSIX-compatible shell. On many systems, this is &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;, but not all, so for greater compatibility you shouldn&#39;t use &lt;code class=&quot;language-bash&quot;&gt;/bin/sh&lt;/code&gt; if you&#39;re using &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;-specific features. For example, on my system I use &lt;code class=&quot;language-bash&quot;&gt;dash&lt;/code&gt; as my &lt;code class=&quot;language-bash&quot;&gt;/bin/sh&lt;/code&gt;, which is more minimal, but more performant.&lt;/p&gt;
&lt;p&gt;I would usually use &lt;code class=&quot;language-bash&quot;&gt;/bin/sh&lt;/code&gt; for scripting, but in this case I wanted to use the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$RANDOM&lt;/span&gt;&lt;/code&gt; variable, which isn&#39;t present in all shells, so I did &lt;code class=&quot;language-bash&quot;&gt;/usr/bin/env &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt; instead.&lt;/p&gt;
&lt;h2 id=&quot;part-2%3A-the-infinite-loop&quot; tabindex=&quot;-1&quot;&gt;Part 2: The Infinite Loop&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# …&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pretty self-explanatory what this does: while the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;/code&gt; command succeeds (which will always be the case), the action inside the loop will be executed, effectively executing repeatedly. We&#39;re using this to keep prompting for new commands. Now, there are a couple ways, still, to break this loop:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Run the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt;&lt;/code&gt; command from the script; this exits the loop. Often people don&#39;t know how long a loop will run or exactly what condition will end it, so they&#39;ll create an infinite loop and just call &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;break&lt;/span&gt;&lt;/code&gt; when they&#39;re done with it.&lt;/li&gt;
&lt;li&gt;Hit &lt;kbd&gt;^C&lt;/kbd&gt; (&lt;kbd&gt;ctrl&lt;/kbd&gt; + &lt;kbd&gt;c&lt;/kbd&gt;) while the script is running. This is the approach we&#39;re expecting users to take; when they&#39;re done with &lt;code class=&quot;language-bash&quot;&gt;moosh&lt;/code&gt;, they can just hit &lt;kbd&gt;^C&lt;/kbd&gt; and exit.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, let&#39;s look at what will happen endlessly inside this loop.&lt;/p&gt;
&lt;h2 id=&quot;part-3%3A-taking-input&quot; tabindex=&quot;-1&quot;&gt;Part 3: Taking Input&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$ &quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; input
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$input&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# …&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, we want a &lt;a href=&quot;https://tty1.blog/articles/anatomy-of-a-command/&quot;&gt;shell prompt&lt;/a&gt;. We don&#39;t need anything fancy (since people can&#39;t actually &lt;em&gt;do&lt;/em&gt; anything in this shell), so we&#39;ll just use &lt;code class=&quot;language-bash&quot;&gt;$ &lt;/code&gt; as our prompt.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$ &quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By using &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt;&lt;/code&gt; with no arguments, we&#39;re printing out the string without a line break, so user input will happen on the same line.&lt;/p&gt;
&lt;p&gt;Now, we want to take the user&#39;s command into a variable, &lt;code class=&quot;language-bash&quot;&gt;input&lt;/code&gt;. We can use the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt;&lt;/code&gt; command for that.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; input
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We don&#39;t actually care &lt;em&gt;what&lt;/em&gt; the input is, since we&#39;re going to do the same thing regardless. But we do want to make sure there &lt;em&gt;is&lt;/em&gt; input; we can use an &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;/code&gt; statement to check that the user did input something, and if not skip responding.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$input&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# …&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;part-4%3A-the-response&quot; tabindex=&quot;-1&quot;&gt;Part 4: The Response&lt;/h2&gt;
&lt;p&gt;Now that we know the user has inputted something, we can respond!&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mo&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;o&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;O&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;…&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s start with the beginning and ending &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt;&lt;/code&gt; statements.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mo&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# …&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;…&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
&lt;p&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt;&lt;/code&gt; with the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt;&lt;/code&gt; flag essentially does the same thing as the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt;&lt;/code&gt; statement we used earlier: print out some text without a new line afterward. I could&#39;ve used either exclusively, but wanted to show you both options.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Here, we start the line with &amp;quot;Mo&amp;quot; and end it with &amp;quot;…&amp;quot;. Between these two segments, we&#39;ll be outputting a random number of &amp;quot;o&amp;quot;s.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# …&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Above, we see one of my favorite tricks: piping a command&#39;s output to a while loop. That lets us execute an action for each line; in this case the line will be stored in the &lt;code class=&quot;language-bash&quot;&gt;n&lt;/code&gt; variable. Now, what&#39;s going on with the command we&#39;re passing to the loop?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; …&lt;/code&gt; - the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt;&lt;/code&gt; command outputs all the numbers between and including the two we specify. We start at &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt; and continue to the result of the tricky bit of this line, which will essentially spit out a random number between 1 and 15. By piping this to &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;/code&gt;, we&#39;ll be executing the contents of &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;/code&gt; a random number of times between 1 and 15.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;…&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; - the double parentheses let us evaluate a mathematical expression as our argument. For example, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; would put &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;/code&gt; in its place.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$RANDOM&lt;/span&gt; % &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; + &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt; - &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$RANDOM&lt;/span&gt;&lt;/code&gt; is a special variable that&#39;ll return a random number. &lt;code class=&quot;language-bash&quot;&gt;%&lt;/code&gt; is an operator that returns the remainder of the first number when divided by the second. This&#39;ll in effect get us a random integer from 0 to 14; we then add 1 to get a random number from 1 to 15 (which doesn&#39;t matter in this case, but I wanted to illustrate the principle).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And, finally, we get to output the &amp;quot;o&amp;quot;s. We&#39;re inside the loop, now, which means whatever commands we put will be executed from 1 to 15 times. We could simply just do this:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;o&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But, to have a little more fun, let&#39;s randomly use either an &lt;code class=&quot;language-bash&quot;&gt;o&lt;/code&gt; or an &lt;code class=&quot;language-bash&quot;&gt;O&lt;/code&gt; to add more &lt;em&gt;character&lt;/em&gt; to our moos.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;The plural of &amp;quot;moo&amp;quot; is &amp;quot;moos&amp;quot;. I think. Possibly not. Don&#39;t quote me on it.&lt;/p&gt;
&lt;/aside&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;o&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;O&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most of this is pretty straightforward. If &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; is &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;, output an &amp;quot;o&amp;quot;, if not, a &amp;quot;O&amp;quot;.&lt;/p&gt;
&lt;p&gt;Now, what is &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;? Well, let&#39;s think back to our last use of &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$RANDOM&lt;/span&gt;&lt;/code&gt;. &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$RANDOM&lt;/span&gt; % &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt; represents the remainder of some random integer divided by two. The only possible outputs are &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt; (it divides evenly by 2) and &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt; (it&#39;s an odd number, with one remainder), effectively running the first command half the time and the second command for the other half.&lt;/p&gt;
&lt;p&gt;Wow, that&#39;s everything.&lt;/p&gt;
&lt;h2 id=&quot;putting-it-all-together&quot; tabindex=&quot;-1&quot;&gt;Putting it All Together&lt;/h2&gt;
&lt;p&gt;Let&#39;s take another look at the completed script, shall we?&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$ &quot;&lt;/span&gt;
	&lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; input
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$input&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mo&quot;&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;$RANDOM &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
				&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;o&quot;&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
				&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;O&quot;&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;…&quot;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this script we:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Establish the interpreter as &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;, using &lt;code class=&quot;language-bash&quot;&gt;/usr/bin/env&lt;/code&gt; to find the path to &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Enter an infinite loop&lt;/li&gt;
&lt;li&gt;Take user input, with &lt;code class=&quot;language-bash&quot;&gt;$ &lt;/code&gt; as a prompt&lt;/li&gt;
&lt;li&gt;Output a random number of &amp;quot;o&amp;quot;s—half capital and half lowercase—between &lt;code class=&quot;language-bash&quot;&gt;Mo&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;…&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&#39;s try it! Put the code into a file (I use one named &lt;code class=&quot;language-bash&quot;&gt;moosh&lt;/code&gt;), and run it:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;
moosh
$ ./moosh
bash: ./moosh: Permission denied
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Uh oh, what happened?&lt;/p&gt;
&lt;p&gt;The answer is simple: we haven&#39;t told your OS that &lt;code class=&quot;language-bash&quot;&gt;./moosh&lt;/code&gt; is a file you can execute. Now, you could work around this by passing the file to &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt; directly (&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt; ./moosh&lt;/code&gt;), but there&#39;s a better way.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; +x ./moosh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives us permission to execute the file.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;I&#39;m planning to do a later article on Linux file permissions, but am still doing my research. &lt;a href=&quot;https://tty1.blog/subscribe/&quot;&gt;Subscribe to the Atom Feed&lt;/a&gt; so you&#39;ll know when it comes out!&lt;/p&gt;
&lt;/aside&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;benjamin@tty1.blog ~&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $ ./moosh
$ █
&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
&lt;p&gt;I used a slightly more complex prompt for &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt; above to make clear the difference between &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&#39;s output and &lt;code class=&quot;language-bash&quot;&gt;moosh&lt;/code&gt;&#39;s output.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Hooray! &lt;code class=&quot;language-bash&quot;&gt;moosh&lt;/code&gt; has launched! Let&#39;s try some commands:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ping&lt;/span&gt; tty1.blog
MooooooooOOoOooOo…
$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;This is the Moo Shell&quot;&lt;/span&gt;
MooOOO…
$ &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; ./moosh
MoOoOooOoO…
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It works! Give yourself a pat on the back. 🎉&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope that, as silly as this project was, walking through it step by step helped you get a picture of how bash scripting works. I&#39;ll likely point to this as an example in the future so that I can go in a little less detail if we walk our way through scripts again.&lt;/p&gt;
&lt;p&gt;I had fun, I hope you did too. I&#39;m always learning myself and am open to feedback on &lt;code class=&quot;language-bash&quot;&gt;moosh&lt;/code&gt; and how I could have made it better or feedback on my explanation in this article; if you have comments or concerns, I&#39;d be gratified if you&#39;d leave a reply down below.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ say-goodbye
MoooOoooOoO…
&lt;/code&gt;&lt;/pre&gt;</content>
		<updated>2023-09-13T00:58:02.000Z</updated>
		<published>2023-09-13T00:58:02.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/shell-yes/</id>
		<link href="https://tty1.blog/articles/shell-yes/" rel="alternate"/>
		<title>Shell, Yes!</title>
		<author>
			<name></name>
		</author>
		<summary>For any Linux enthusiast, administrator, developer, systems engineer, or overall neck-beard, the terminal is the meat and potatoes of a good chunk of day-to-day work and interaction with Linux. Your terminal&#39;s shell is a powerful tool to make your work easier and more fun to work with.

Configuring your shell to work for your needs is a useful skill to have and is at the heart of automation in your terminal environment. We computer nerds are lazy and love tweaking computer environments to do work for us.</summary>
		<content type="html">&lt;p&gt;For any Linux enthusiast, administrator, developer, systems engineer, or overall neck-beard, the terminal is the meat and potatoes of a good chunk of day-to-day work and interaction with Linux. Your terminal&#39;s shell is a powerful tool to make your work easier and more fun to work with.&lt;/p&gt;
&lt;p&gt;Configuring your shell to work for your needs is a useful skill to have and is at the heart of automation in your terminal environment. We computer nerds are lazy and love tweaking computer environments to do work for us.&lt;/p&gt;
&lt;h2 id=&quot;anatomy&quot; tabindex=&quot;-1&quot;&gt;Anatomy&lt;/h2&gt;
&lt;p&gt;I&#39;m going to break down shell configurations into several different files (more details in &lt;a href=&quot;https://unix.stackexchange.com/a/71258&quot;&gt;this awesome Unix StackExchange answer&lt;/a&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;rc&lt;/code&gt; - controls our shell&#39;s interactive behavior.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt;&lt;/code&gt; - contains exported environment variables.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;aliases&lt;/code&gt; - contains—you guessed it—our aliases.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are a few other files, but I&#39;ll mention them later.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;I use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; as my shell, so this post will focus on it. The principles should stay the same for your shell of choice.&lt;/p&gt;
&lt;/aside&gt;
&lt;h3 id=&quot;the-rc-file&quot; tabindex=&quot;-1&quot;&gt;The &lt;code class=&quot;language-bash&quot;&gt;rc&lt;/code&gt; file&lt;/h3&gt;
&lt;p&gt;An &lt;code class=&quot;language-bash&quot;&gt;rc&lt;/code&gt; file (or a &lt;a href=&quot;https://www.baeldung.com/linux/rc-files&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;RUNCOM&lt;/code&gt; file&lt;/a&gt;) is a file or directory designated to hold configurations for an interactive shell. Modern shells usually come preinstalled with an &lt;code class=&quot;language-bash&quot;&gt;rc&lt;/code&gt; file with several example configuration lines and inline comments explaining them, and these example files can vary between Linux distributions.&lt;/p&gt;
&lt;p&gt;This is the best place to start your configurations, and there are plenty of experienced users out there who run their shell with all of its configurations in this file alone. The &lt;code class=&quot;language-bash&quot;&gt;rc&lt;/code&gt; is arguably the most important config file for your shell. (The second most important is the file that makes it look cool.)&lt;/p&gt;
&lt;p&gt;Let&#39;s start configuring this thing. We&#39;ll continue using &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; as our example here, and will pull the important lines from the generated &lt;code class=&quot;language-bash&quot;&gt;zshrc&lt;/code&gt; that comes with a &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; install, as well as add a few of our own.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# .zshrc&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;HIST_STAMPS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mm/dd/yyyy&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;ENABLE_CORRECTION&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ~/.aliases &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; ~/.aliases
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dircolors&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;s/ 4[0-9];/ 01;/; s/;4[0-9];/;01;/g; s/;4[0-9] /;01 /&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;dircolors&lt;/span&gt; /dev/stdin&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function-name function&quot;&gt;precmd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;typeset&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; deactivate &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;/dev/null&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token for-or-select variable&quot;&gt;activate&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; ./venv/bin/activate ./.venv/bin/activate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$activate&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
                &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$activate&lt;/span&gt;&quot;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$SSH_CONNECTION&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$TMUX&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; tmux&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&#39;ll break this down line-by-line:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;HIST_STAMPS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mm/dd/yyyy&quot;&lt;/span&gt;&lt;/code&gt; describes the timestamp formatting for our shell history.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;ENABLE_CORRECTION&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;/code&gt; sets command-line autocorrection.&lt;/li&gt;
&lt;li&gt;The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;/code&gt; block checks for our &lt;code class=&quot;language-bash&quot;&gt;.aliases&lt;/code&gt; config file, and makes sure &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; sees it.&lt;/li&gt;
&lt;li&gt;The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;eval&lt;/span&gt;&lt;/code&gt; statement removes the background colors of directories when running &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt; commands.&lt;/li&gt;
&lt;li&gt;The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; precmd&lt;/code&gt; will activate a venv when navigating to a directory that holds a venv.&lt;/li&gt;
&lt;li&gt;Lastly, the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;/code&gt; block at the bottom will activate &lt;code class=&quot;language-bash&quot;&gt;tmux&lt;/code&gt; when the shell is launched, as long as it&#39;s not over a &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt;&lt;/code&gt; connection.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-env-file&quot; tabindex=&quot;-1&quot;&gt;The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt;&lt;/code&gt; file&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt;&lt;/code&gt; (environment) file contains our exported variables, we want to put variables that other programs will see or use in here. Some examples (from the &lt;a href=&quot;https://unix.stackexchange.com/a/71258&quot;&gt;previous StackExchange answer&lt;/a&gt;) include your &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&lt;/code&gt;, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$EDITOR&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$PAGER&lt;/span&gt;&lt;/code&gt; environment variables. The zsh &lt;code class=&quot;language-bash&quot;&gt;.zshenv&lt;/code&gt; file is always &lt;a href=&quot;https://ss64.com/bash/source.html&quot;&gt;sourced&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are some lines from my &lt;code class=&quot;language-bash&quot;&gt;.zshenv&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# .zshenv&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DOTFILES&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.dotfiles
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DOCKER&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;podman
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/bin:/usr/local/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;LANG&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;en_US.UTF-8

&lt;span class=&quot;token comment&quot;&gt;# Preferred editor for local and remote sessions&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$SSH_CONNECTION&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;EDITOR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;vim&#39;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;EDITOR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;hx&#39;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, we create a &lt;code class=&quot;language-bash&quot;&gt;DOTFILES&lt;/code&gt; variable that describes the location of our dotfiles (I&#39;ll go over this later, but this is where we&#39;ll store our configs for backups and version control).&lt;/p&gt;
&lt;p&gt;Next, I prefer to use Podman over Docker, so for convenience, I have the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$DOCKER&lt;/span&gt;&lt;/code&gt; env variable point to &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;podman&lt;/span&gt;&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;Then, a line that adds &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/bin&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;/usr/local/bin&lt;/code&gt; to &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&lt;/code&gt;, then we set &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$LANG&lt;/span&gt;&lt;/code&gt; to &lt;code class=&quot;language-bash&quot;&gt;en_US.UTF-8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;/code&gt; block here at the end, we set &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$EDITOR&lt;/span&gt;&lt;/code&gt; to Helix if we&#39;re not on a &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt;&lt;/code&gt; connection, and Vim if we are connected via &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now we&#39;ll take a look at the contents of the &lt;code class=&quot;language-bash&quot;&gt;.aliases&lt;/code&gt; file we dropped into our &lt;code class=&quot;language-bash&quot;&gt;.zshrc&lt;/code&gt; earlier.&lt;/p&gt;
&lt;h3 id=&quot;the-aliases-file&quot; tabindex=&quot;-1&quot;&gt;The &lt;code class=&quot;language-bash&quot;&gt;aliases&lt;/code&gt; file&lt;/h3&gt;
&lt;p&gt;This one will be brief, as everyone&#39;s aliases are very different from everyone else&#39;s. Most of my aliases are &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt;&lt;/code&gt; commands to quickly jump to other hosts, but there&#39;s a few others that I use as well.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# .aliases&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# grep&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;grep --color=auto&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fgrep&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;fgrep --color=auto&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;egrep&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;egrep --color=auto&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# cat&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;bat --theme Nord -p&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ls &lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ll&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;ls -Al&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;la&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;ls -A&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;ls --color=auto&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;ls -CF&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# dir&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;dir --color=auto&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;vdir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;vdir --color=auto&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# opening files in your $EDITOR&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ali&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;$EDITOR ~/.aliases&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;zrc&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;$EDITOR ~/.zshrc&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# source config files&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;source ~/.aliases&#39;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;source ~/.zshrc&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# system updates (this is for rpm-based systems like Fedora)&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;upd&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;sudo dnf upgrade -y &amp;amp;&amp;amp; flatpak update&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are pretty straight forward. We use the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt;&lt;/code&gt; keyword followed by a key-value pair describing our alias and the command it represents. The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt;, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt;&lt;/code&gt;, and &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;dir&lt;/span&gt;&lt;/code&gt; aliases here can be copied and pasted without issue; the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt;&lt;/code&gt; alias will require &lt;a href=&quot;https://github.com/sharkdp/bat&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bat&lt;/code&gt;&lt;/a&gt;, a fancy &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt;&lt;/code&gt; alternative. The rest are shortcuts to open or source config files in the set &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$EDITOR&lt;/span&gt;&lt;/code&gt; (from the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;env&lt;/span&gt;&lt;/code&gt; file), plus one to run system updates on Fedora.&lt;/p&gt;
&lt;p&gt;Zsh will read these as though they were directly in the &lt;code class=&quot;language-bash&quot;&gt;.zshrc&lt;/code&gt;. I like to keep the aliases separate, it feels more organized to me, but there&#39;s no issue at all with dropping them straight into the &lt;code class=&quot;language-bash&quot;&gt;rc&lt;/code&gt; if you like everything in one place. They will both work the same.&lt;/p&gt;
&lt;p&gt;These examples work independently from one another; when you come across examples like these, try experimenting with them line-by-line, and work them into your own configuration, instead of dropping them all blindly in your config.&lt;/p&gt;
&lt;h2 id=&quot;how-your-shell-loads-its-configs&quot; tabindex=&quot;-1&quot;&gt;How Your Shell Loads Its Configs&lt;/h2&gt;
&lt;p&gt;If you want to segment out your config options, aliases, environment variables, functions, etc. into these separate files, then you should understand the order in which your shell loads them, to avoid any conflicts and redundancies.&lt;/p&gt;
&lt;p&gt;These config files are really just scripts, like any other shell script, that are called when the shell is run or exited.&lt;/p&gt;
&lt;p&gt;Here&#39;s how &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; will load its config files, from &lt;a href=&quot;https://shreevatsa.wordpress.com/2008/03/30/zshbash-startup-files-loading-order-bashrc-zshrc-etc/&quot;&gt;this great post&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;Interactive&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;Interactive&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;Script&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;login      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;non-login  &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;/etc/zshenv     &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    A      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    A      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;  A   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.zshenv       &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    B      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    B      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;  B   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;/etc/zprofile   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    C      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.zprofile     &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    D      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;/etc/zshrc      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    E      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    C      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.zshrc        &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    F      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    D      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;/etc/zlogin     &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    G      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.zlogin       &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    H      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.zlogout      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    I      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;/etc/zlogout    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    J      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
&lt;p&gt;If you use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;, here&#39;s a table describing the equivalent files and their load order in &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt; from the &lt;a href=&quot;https://shreevatsa.wordpress.com/2008/03/30/zshbash-startup-files-loading-order-bashrc-zshrc-etc/&quot;&gt;same post&lt;/a&gt;.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Show table&lt;/summary&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;Interactive&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;Interactive&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;Script&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;login      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;non-login  &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;/etc/profile    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;   A       &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;/etc/bash.bashrc&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    A      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.bashrc       &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    B      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.bash_profile &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;   B1      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.bash_login   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;   B2      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.profile      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;   B3      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;BASH_ENV        &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;  A   &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;                &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;~/.bash_logout  &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;    C      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;      &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
+----------------+-----------+-----------+------+
&lt;/code&gt;&lt;/pre&gt;
&lt;/details&gt;
&lt;/aside&gt;
&lt;p&gt;Assuming you&#39;ve launched an interactive &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; login, the shell will check for config files in &lt;code class=&quot;language-bash&quot;&gt;/etc&lt;/code&gt; first, load the contents from those files, then check your home directory.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-bash&quot;&gt;zshenv&lt;/code&gt; file is loaded first, then your &lt;code class=&quot;language-bash&quot;&gt;zprofile&lt;/code&gt; (Here, we want to place our configs for login shells. This is an alternative to the &lt;code class=&quot;language-bash&quot;&gt;login&lt;/code&gt; file (or &lt;code class=&quot;language-bash&quot;&gt;.zlogin&lt;/code&gt;), which is sourced &lt;em&gt;after&lt;/em&gt; the &lt;code class=&quot;language-bash&quot;&gt;rc&lt;/code&gt;). Next is our &lt;code class=&quot;language-bash&quot;&gt;zshrc&lt;/code&gt;, and finally, the &lt;code class=&quot;language-bash&quot;&gt;zlogin&lt;/code&gt;. The &lt;code class=&quot;language-bash&quot;&gt;zlogout&lt;/code&gt; file is executed when you exit the interactive shell.&lt;/p&gt;
&lt;p&gt;Notice that on an interactive non-login instance, our &lt;code class=&quot;language-bash&quot;&gt;zshenv&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;zshrc&lt;/code&gt; files are the only files that are sourced, and the &lt;code class=&quot;language-bash&quot;&gt;zshenv&lt;/code&gt; file is the only file sourced from scripts.&lt;/p&gt;
&lt;h2 id=&quot;bonus%3A-managing-your-dotfiles-with-gnu-stow&quot; tabindex=&quot;-1&quot;&gt;Bonus: Managing Your Dotfiles with GNU Stow&lt;/h2&gt;
&lt;p&gt;So you&#39;ve got all these files now, but how do you organize and manage them? If you&#39;ve consolidated everything to just the &lt;code class=&quot;language-bash&quot;&gt;.zshrc&lt;/code&gt;, then there are no issues with just dropping it in your home directory and leaving it at that, but if you expect your configs to grow and want a way to organize them, keep backups, and use some version control then you can place them all in a git repository and use a symbolic link manager like &lt;a href=&quot;https://www.gnu.org/software/stow/&quot;&gt;GNU Stow&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&#39;ll start by taking a look at &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt; and building out a directory structure that it can use to manage our dotfiles. Create a directory in your &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;&lt;/code&gt; called &lt;code class=&quot;language-bash&quot;&gt;.dotfiles&lt;/code&gt; and create a &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; subdirectory inside it, then move (&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt;&lt;/code&gt;, not &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt;&lt;/code&gt;) the dotfiles we&#39;ve worked on to that directory, like so:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tree &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; ~/.dotfiles 
/home/btp/.dotfiles/
└── &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
    ├── .aliases
    ├── .zshenv
    └── .zshrc

&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; directory, &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; files
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code class=&quot;language-bash&quot;&gt;.dotfiles&lt;/code&gt; directory will be our root directory when using &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt;, and inside this directory we&#39;ll be storing our &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt; &amp;quot;packages&amp;quot;, which we&#39;ll be calling &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt; on to install.&lt;/p&gt;
&lt;p&gt;In this example, we&#39;ll be creating a &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; package which will install the three config files we&#39;ve created to the target directory we give to &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By default, the target directory is the directory above the &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt; root directory, which is our home directory in this case. If you want to change the target directory, add the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-T&lt;/span&gt; /path/to/target&lt;/code&gt; flag and argument.&lt;/p&gt;
&lt;p&gt;First, let&#39;s install this &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; package with &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt;. Run the following command in your &lt;code class=&quot;language-bash&quot;&gt;.dotfiles&lt;/code&gt; directory.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;~/.dotfiles&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $ stow &lt;span class=&quot;token parameter variable&quot;&gt;--stow&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will call stow on our &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;&lt;/code&gt; package, and install our dotfiles in the directory above our &lt;code class=&quot;language-bash&quot;&gt;.dotfiles&lt;/code&gt; directory, which is &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;&lt;/code&gt;. The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--stow&lt;/span&gt;&lt;/code&gt; flag can also be &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-S&lt;/span&gt;&lt;/code&gt;. Stow uses symbolic links, and &amp;quot;installs&amp;quot; by creating the symbolic link in the target directory.&lt;/p&gt;
&lt;p&gt;This is the same as if you would run &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; /home/user/.dotfiles/zsh/.zshrc /home/user/&lt;/code&gt; for each of these files.&lt;/p&gt;
&lt;p&gt;Now consider the following &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt; packages:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tree &lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt; ~/.dotfiles
/home/btp/.dotfiles
├── alacritty
│   └── .config
│       └── alacritty
│           └── alacritty.toml
└── &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
    ├── .aliases
    ├── .zshenv
    └── .zshrc

&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; directories, &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; files
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, we&#39;ve added a config package for the terminal Alacritty. Stow will check the full path under the package, and mirror it to our target location. When running the &lt;code class=&quot;language-bash&quot;&gt;stow&lt;/code&gt; command on this package, it will add the full config path &lt;code class=&quot;language-bash&quot;&gt;~/.config/alacritty/alacritty.toml&lt;/code&gt;, which is exactly where we want it.&lt;/p&gt;
&lt;p&gt;You can layer your Stow root directory however you want, but when you install packages, you&#39;ll need to navigate to the directory that holds the package itself; Stow will not accept a path to a package:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# this will NOT work.&lt;/span&gt;
~&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $ stow &lt;span class=&quot;token parameter variable&quot;&gt;-S&lt;/span&gt; .dotfiles/zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I keep my &lt;code class=&quot;language-bash&quot;&gt;.dotfiles&lt;/code&gt; in &lt;a href=&quot;https://codeberg.org/btp/dotfiles&quot;&gt;a git repository&lt;/a&gt; and hold configs for multiple operating systems there, then navigate to the relevant OS directory for installs, like so.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;tree ~/.dotfiles/
└── dots
    ├── linux
    │   ├── alacritty
    │   ├── awesome
    │   ├── helix
    │   ├── nushell
    │   ├── nvim
    │   ├── p10k
    │   ├── powershell
    │   ├── starship
    │   ├── tmux
    │   └── &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
    ├── macos
    │   ├── alacritty
    │   ├── helix
    │   ├── nushell
    │   ├── nvim
    │   ├── p10k
    │   ├── powershell
    │   ├── starship
    │   ├── tmux
    │   └── &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
    └── wsl
        ├── helix
        ├── nushell
        ├── p10k
        ├── powershell
        ├── starship
        ├── tmux
        └── &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I tried to limit the scope of this article to avoid confusion, and also to avoid a massive post. This topic is very subjective, so take these examples as just that, examples. I&#39;ve found what works for me when building and managing my config files in a scaleable way, and I hope this has helped you as well. Enjoy!&lt;/p&gt;</content>
		<updated>2023-07-14T13:29:18.000Z</updated>
		<published>2023-07-14T13:29:18.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/terminal-music-management/</id>
		<link href="https://tty1.blog/articles/terminal-music-management/" rel="alternate"/>
		<title>Terminal-Based Music</title>
		<author>
			<name></name>
		</author>
		<summary>About a year ago, I stopped using Spotify for my music, instead moving to local audio files. I&#39;ve never regretted that decision. When I started transitioning to a terminal-based workflow, though, I had to find good utilities to manage and play my collection.

I think that the results have been far more useful than the graphical apps I used to use were.</summary>
		<content type="html">&lt;p&gt;About a year ago, I stopped using Spotify for my music, instead moving to local audio files. I&#39;ve never regretted that decision. When I started transitioning to a terminal-based workflow, though, I had to find good utilities to manage and play my collection.&lt;/p&gt;
&lt;p&gt;I think that the results have been far more useful than the graphical apps I used to use were.&lt;/p&gt;
&lt;h2 id=&quot;acquiring-music&quot; tabindex=&quot;-1&quot;&gt;Acquiring Music&lt;/h2&gt;
&lt;p&gt;My preferred method of acquiring music is to buy used CDs and rip them. My tastes in music are fairly old, mostly classical, big band, etc., so I can get away with this. I go to Half Price Books and buy up a bunch of clearanced CDs for 50¢ each.&lt;/p&gt;
&lt;p&gt;You may decide to pursue a &amp;quot;less legal&amp;quot; solution, but I won&#39;t comment on that, except to point out a helpful alias I have set up for &lt;a href=&quot;https://github.com/yt-dlp/yt-dlp&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;yt-dlp&lt;/code&gt;&lt;/a&gt;, to download audio from YouTube:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; yt-audio&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;yt-dlp -x --audio-format mp3&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I can simply run &lt;code class=&quot;language-bash&quot;&gt;yt-audio &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;link to song or playlist&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt; to download a song or album to the current directory.&lt;/p&gt;
&lt;p&gt;On to what I do with my CDs. I&#39;ve settled on &lt;a href=&quot;https://abcde.einval.com/wiki/&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;abcde&lt;/code&gt;&lt;/a&gt;. Once again, I&#39;ve set up an alias to automatically apply settings I want.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;rip&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;abcde -Vx -o flac&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-V&lt;/span&gt;&lt;/code&gt; - Makes the output more verbose, making sure I get all status updates. I like verbose output. :)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-x&lt;/span&gt;&lt;/code&gt; - Ejects the disk once &lt;code class=&quot;language-bash&quot;&gt;abcde&lt;/code&gt; is finished.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; flac&lt;/code&gt; - Outputs the files in the &lt;code class=&quot;language-bash&quot;&gt;flac&lt;/code&gt; format&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/downloads&lt;/code&gt;, run &lt;code class=&quot;language-bash&quot;&gt;rip&lt;/code&gt;, and &lt;code class=&quot;language-bash&quot;&gt;abcde&lt;/code&gt; creates a subfolder with all the files, trying to see if it can find information on the album and adding metadata if it does.&lt;/p&gt;
&lt;h2 id=&quot;managing-the-library&quot; tabindex=&quot;-1&quot;&gt;Managing the Library&lt;/h2&gt;
&lt;p&gt;The magic of my music management happens through &lt;a href=&quot;https://beets.io/&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;beets&lt;/code&gt;&lt;/a&gt;, which bills itself as &amp;quot;the music geek&#39;s media organizer&amp;quot;. If you&#39;re interested in my configuration, I have it posted &lt;a href=&quot;https://codeberg.org/benjaminhollon/.dotfiles/src/branch/main/.config/beets/config.yaml&quot;&gt;in my dotfiles&lt;/a&gt;. Basically, it sets where I store my music, says to move music files rather than just copying them, and gets album art when importing.&lt;/p&gt;
&lt;p&gt;Once I&#39;ve ripped a bunch of CDs into &lt;code class=&quot;language-bash&quot;&gt;~/downloads&lt;/code&gt; with &lt;code class=&quot;language-bash&quot;&gt;abcde&lt;/code&gt;, I run &lt;code class=&quot;language-bash&quot;&gt;beet im &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt; in &lt;code class=&quot;language-bash&quot;&gt;~/downloads&lt;/code&gt; to import all the albums. It automatically looks for album metadata from &lt;a href=&quot;https://musicbrainz.org/&quot;&gt;MusicBrainz&lt;/a&gt;, adds it to the files, then sorts them into your music collection. Mine is set up to be at &lt;code class=&quot;language-bash&quot;&gt;~/music&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you want to learn all of &lt;code class=&quot;language-bash&quot;&gt;beets&lt;/code&gt;&#39;s features, it has &lt;a href=&quot;https://beets.readthedocs.io/en/stable/index.html&quot;&gt;online documentation&lt;/a&gt; available. There are also manpages: &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; beet&lt;/code&gt; for the CLI and &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; beetsconfig&lt;/code&gt; for information on configuring &lt;code class=&quot;language-bash&quot;&gt;beets&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;playing-music&quot; tabindex=&quot;-1&quot;&gt;Playing Music&lt;/h2&gt;
&lt;p&gt;I play music through &lt;a href=&quot;https://cmus.github.io/&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;cmus&lt;/code&gt;&lt;/a&gt;. It&#39;s pretty self-explanatory; if you don&#39;t understand something, see &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; cmus&lt;/code&gt;. You&#39;ll probably want to take a look there at first to find all the default keybindings.&lt;/p&gt;
&lt;p&gt;One thing you will have to do is add music from your collection. Go to the &amp;quot;Browser&amp;quot; view with &lt;kbd&gt;6&lt;/kbd&gt;, use arrows or &lt;kbd&gt;j&lt;/kbd&gt; and &lt;kbd&gt;k&lt;/kbd&gt; to highlight the directory you store your music in, then use &lt;kbd&gt;a&lt;/kbd&gt; to add everything in it to your Library (at which point it will be viewable in the default view; you can get back there with &lt;kbd&gt;1&lt;/kbd&gt;). You&#39;ll want to do this again whenever you add get new music.&lt;/p&gt;
&lt;h2 id=&quot;getting-metadata&quot; tabindex=&quot;-1&quot;&gt;Getting Metadata&lt;/h2&gt;
&lt;p&gt;I sometimes want to see what&#39;s playing without going over to &lt;code class=&quot;language-bash&quot;&gt;cmus&lt;/code&gt;. In SwayWM, my window manager, I can set it to run commands or scripts when a keyboard shortcut is triggered.&lt;/p&gt;
&lt;p&gt;I use &lt;code class=&quot;language-bash&quot;&gt;playerctl&lt;/code&gt; to get information about what&#39;s currently playing, which has worked for most music players I&#39;ve tried. Here&#39;s my custom &lt;code class=&quot;language-bash&quot;&gt;notify-playing&lt;/code&gt; script:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#! /bin/sh&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;playerctl metadata&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$metadata&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;:title&lt;span class=&quot;token entity&quot; title=&quot;&#92;b&quot;&gt;&#92;b&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;BEGIN{FS=&quot; {2,}&quot;}{ print $3 }&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;artist&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$metadata&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;:artist&lt;span class=&quot;token entity&quot; title=&quot;&#92;b&quot;&gt;&#92;b&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;BEGIN{FS=&quot; {2,}&quot;}{ print $3 }&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;album&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$metadata&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;:album&lt;span class=&quot;token entity&quot; title=&quot;&#92;b&quot;&gt;&#92;b&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;BEGIN{FS=&quot; {2,}&quot;}{ print $3 }&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;artUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$metadata&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;:artUrl&lt;span class=&quot;token entity&quot; title=&quot;&#92;b&quot;&gt;&#92;b&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;BEGIN{FS=&quot; {2,}&quot;}{ print $3 }&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;notify-send&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$title&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$artist&lt;/span&gt; – &lt;span class=&quot;token variable&quot;&gt;$album&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$artUrl&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;notify-send&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Nothing playing.&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Put it in a folder in your &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;&lt;/code&gt;. Now, when &lt;code class=&quot;language-bash&quot;&gt;notify-playing&lt;/code&gt; is run, you get a notification with the title, album, and artist of the song playing.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;&lt;code class=&quot;language-bash&quot;&gt;cmus&lt;/code&gt; does not include &lt;code class=&quot;language-bash&quot;&gt;artUrl&lt;/code&gt; in its metadata, but I put that in anyway in case I ever use a player that does. I think there&#39;s also a script you can add to cmus to add support for &lt;code class=&quot;language-bash&quot;&gt;artUrl&lt;/code&gt;, though I haven&#39;t tried it.&lt;/p&gt;
&lt;p&gt;Also, to give credit where it&#39;s due, &lt;a href=&quot;https://rldane.space/&quot;&gt;R.L. Dane&lt;/a&gt; helped a bit with this script, specifically suggesting a better Regular Expression for awk to use in parsing the metadata.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id=&quot;bonus%3A-streaming-music&quot; tabindex=&quot;-1&quot;&gt;Bonus: Streaming Music&lt;/h2&gt;
&lt;p&gt;While it&#39;s not strictly for the terminal, I use &lt;a href=&quot;https://github.com/sentriz/gonic&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;gonic&lt;/code&gt;&lt;/a&gt; to stream music to my phone from my collection, since the collection is too large to store full-quality copies on my phone. I won&#39;t go into all the details, but it&#39;s a streaming backend that works well with &lt;code class=&quot;language-bash&quot;&gt;beets&lt;/code&gt;, so I thought I&#39;d mention it.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This whole workflow won&#39;t be perfect for everyone. Still, parts of it can be integrated into whatever your ideal music setup is. Specifically, I think &lt;code class=&quot;language-bash&quot;&gt;beets&lt;/code&gt; is a tool can fit into and improve any setup.&lt;/p&gt;
&lt;p&gt;Crafting your music setup is a journey, and it&#39;s different for everyone. Once you&#39;ve figured out the specifics of your setup, do let me know! I&#39;m happy to compare notes and perhaps learn some tips myself.&lt;/p&gt;
&lt;p&gt;Happy listening!&lt;/p&gt;</content>
		<updated>2023-06-10T14:06:55.000Z</updated>
		<published>2023-06-10T14:06:55.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/xdg-user-dirs/</id>
		<link href="https://tty1.blog/articles/xdg-user-dirs/" rel="alternate"/>
		<title>Leveling Up Your Filetree with xdg-user-dirs</title>
		<author>
			<name></name>
		</author>
		<summary>Have you ever noticed that there are certain directories everyone has? `~/Documents`, `~/Downloads`, `~/Desktop`, and so forth? Some of them you don&#39;t need, some of them you might wish were named differently, but any time you rename or delete them, the originals *reappear*?

You see, these directories follow a standard so that all programs know where they are—with the right tools under your belt, you can customize them.</summary>
		<content type="html">&lt;p&gt;Have you ever noticed that there are certain directories everyone has? &lt;code class=&quot;language-bash&quot;&gt;~/Documents&lt;/code&gt;, &lt;code class=&quot;language-bash&quot;&gt;~/Downloads&lt;/code&gt;, &lt;code class=&quot;language-bash&quot;&gt;~/Desktop&lt;/code&gt;, and so forth? Some of them you don&#39;t need, some of them you might wish were named differently, but any time you rename or delete them, the originals &lt;em&gt;reappear&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;You see, these directories follow a standard so that all programs know where they are—with the right tools under your belt, you can customize them.&lt;/p&gt;
&lt;h2 id=&quot;meet-xdg-user-dirs&quot; tabindex=&quot;-1&quot;&gt;Meet &lt;code class=&quot;language-bash&quot;&gt;xdg-user-dirs&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://freedesktop.org/wiki/Software/xdg-user-dirs/&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;xdg-user-dirs&lt;/code&gt;&lt;/a&gt; is a set of two utilities that manages the placement of standard directories on your installation. Most people already have it, though they may not know about it, since it comes with many major Desktop Environments.&lt;/p&gt;
&lt;p&gt;If you don&#39;t have it, go ahead and install it now.&lt;/p&gt;
&lt;p&gt;To get started, run this command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ xdg-user-dirs-update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command creates all of the configured folders on your system. If it&#39;s not already configured, it will create the configuration file for you.&lt;/p&gt;
&lt;p&gt;By default, these are the folders it creates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Desktop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Documents&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Downloads&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Music&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Pictures&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Public&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Templates&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Videos&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that everything&#39;s set up, let&#39;s customize these folders to our taste.&lt;/p&gt;
&lt;h2 id=&quot;customizing-your-user-directories&quot; tabindex=&quot;-1&quot;&gt;Customizing Your User Directories&lt;/h2&gt;
&lt;p&gt;There are two configuration files to worry about. If you want to configure the default folders for every user on your installation, you can edit &lt;code class=&quot;language-bash&quot;&gt;/etc/xdg/user-dirs.defaults&lt;/code&gt;. To configure user-specific folders, edit &lt;code class=&quot;language-bash&quot;&gt;~/.config/user-dirs.dirs&lt;/code&gt;.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;You can actually customize the location of configuration files! The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$XDG_CONFIG_HOME&lt;/span&gt;&lt;/code&gt; environment variable controls this; it defaults to &lt;code class=&quot;language-bash&quot;&gt;~/.config&lt;/code&gt;. If you have it customized to, say, &lt;code class=&quot;language-bash&quot;&gt;~/configuration&lt;/code&gt;, the user-dirs configuration file would be at &lt;code class=&quot;language-bash&quot;&gt;~/configuration/user-dirs.dirs&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;We&#39;ll be going over how to customize your shell and environment variables in a few weeks, so stay tuned, if you don&#39;t know how.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;By default, you get this:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# This file is written by xdg-user-dirs-update&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# If you want to change or add directories, just edit the line you&#39;re&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# interested in. All local changes will be retained on the next run.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Format is XDG_xxx_DIR=&quot;$HOME/yyy&quot;, where yyy is a shell-escaped&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# homedir-relative path, or XDG_xxx_DIR=&quot;/yyy&quot;, where /yyy is an&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# absolute path. No other format is supported.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# &lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DESKTOP_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Desktop&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOWNLOAD_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Downloads&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Templates&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PUBLICSHARE_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Public&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOCUMENTS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Documents&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_MUSIC_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Music&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PICTURES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Pictures&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_VIDEOS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Videos&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In itself, this is pretty self-explanatory. Let&#39;s do some simple customization and make all of these directory names lowercase, for easier typing in the terminal.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DESKTOP_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/desktop&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOWNLOAD_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/downloads&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/templates&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PUBLICSHARE_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/public&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOCUMENTS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/documents&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_MUSIC_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/music&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PICTURES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/pictures&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_VIDEOS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/videos&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, you could go ahead and lock this in, but this would only create new directories in the new locations; it doesn&#39;t move the current folders. Let&#39;s do that first, so that we don&#39;t have a bunch of extra directories.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Desktop ~/desktop
&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Downloads ~/downloads
&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Templates ~/templates
&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Public ~/public
&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Documents ~/documents
&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Music ~/music
&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Pictures ~/pictures
&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/Videos ~/videos
&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
&lt;p&gt;I&#39;ve removed the shell prompts (&lt;code class=&quot;language-bash&quot;&gt;$&lt;/code&gt;) I usually add to commands for the sake of making this easier to copy/paste. That said, please remember never to copy commands you don&#39;t fully understand into the terminal.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Now that our files are in the right place, let&#39;s update our user directory listings:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ xdg-user-dirs-update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, any compatible program will automatically use the new directories you&#39;ve specified. Hooray!&lt;/p&gt;
&lt;h3 id=&quot;removing-default-directories&quot; tabindex=&quot;-1&quot;&gt;Removing Default Directories&lt;/h3&gt;
&lt;p&gt;Sometimes you don&#39;t want one of the directories that &lt;code class=&quot;language-bash&quot;&gt;xdg-user-dirs&lt;/code&gt; adds by default. I, for example, don&#39;t have any need for &lt;code class=&quot;language-bash&quot;&gt;~/desktop&lt;/code&gt;. Well, let&#39;s try removing it:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOWNLOAD_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/downloads&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/templates&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PUBLICSHARE_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/public&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOCUMENTS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/documents&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_MUSIC_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/music&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PICTURES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/pictures&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_VIDEOS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/videos&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;rmdir&lt;/span&gt; ~/desktop
$ xdg-user-dirs-update
$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;
Desktop documents download music pictures public templates videos
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oops, it reappeared, in the default form. If we check back in our config file, we&#39;ll find this added to the end:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DESKTOP_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/Desktop&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay, so &lt;code class=&quot;language-bash&quot;&gt;xdg-user-dirs&lt;/code&gt; won&#39;t let us remove the default directories. Why? Because there are programs that rely on those folders existing, and &lt;code class=&quot;language-bash&quot;&gt;xdg-user-dirs&lt;/code&gt; doesn&#39;t want them to be missing when those programs go looking.&lt;/p&gt;
&lt;p&gt;So, is there a workaround?
Well, let&#39;s think about this use-case. What do programs usually want to know about the desktop for? Usually so they can put a file or link there for quick access. For me, that&#39;s what the &lt;code class=&quot;language-bash&quot;&gt;downloads&lt;/code&gt; folder tends to be for. Let&#39;s try something:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DESKTOP_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/downloads&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…and it works, even though &lt;code class=&quot;language-bash&quot;&gt;XDG_DOWNLOAD_DIR&lt;/code&gt; is already set to &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/downloads&lt;/code&gt;. You can double up like this, which I find handy.&lt;/p&gt;
&lt;p&gt;You can also set one to a subdirectory:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/documents/templates&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;adding-extra-user-directories&quot; tabindex=&quot;-1&quot;&gt;Adding Extra User Directories&lt;/h3&gt;
&lt;p&gt;Perhaps you want an extra directory defined, besides what the defaults are. I, for example, have extra user directories for my writing, screenshots, and notes:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_WRITING_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/writing&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_SCREENSHOTS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/pictures/screenshots&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_NOTES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/notes&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While these aren&#39;t used by any programs I use, I can reference them in my own scripts. For example, if I have multiple scripts that need to access my notes, I no longer have to update each one if I decide to move my notes; all I need to do is update &lt;code class=&quot;language-bash&quot;&gt;XDG_NOTES_DIR&lt;/code&gt; and run &lt;code class=&quot;language-bash&quot;&gt;xdg-user-dirs-update&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;How do you reference these directories? Let&#39;s learn.&lt;/p&gt;
&lt;h2 id=&quot;using-xdg-user-dir&quot; tabindex=&quot;-1&quot;&gt;Using &lt;code class=&quot;language-bash&quot;&gt;xdg-user-dir&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;To get the location of a user directory, use the &lt;code class=&quot;language-bash&quot;&gt;xdg-user-dir&lt;/code&gt; command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ xdg-user-dir NOTES
/home/benjamin/notes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Want to include this as part of a command? Say, for example, that you have this in a script:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;You have &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; ~/notes/school &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wc&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt; notes from class&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;; anything inside the parentheses is replaced with its output when run as a command. So, let&#39;s use this to update the script:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;You have $(ls &quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;xdg-user-dir NOTES&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;/school&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wc&lt;/span&gt; -l&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; notes from class&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Et voila!&lt;/em&gt; Now, whenever you move your notes and update the user-dir configuration, any scripts using this strategy will automatically work with the new location.&lt;/p&gt;
&lt;h2 id=&quot;closing-thoughts&quot; tabindex=&quot;-1&quot;&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;You don&#39;t have to mess around with your user directories. Much of what I&#39;ve talked about here may not be interesting to you.&lt;/p&gt;
&lt;p&gt;But having the knowledge of what goes on behind the scenes? That&#39;s valuable. And who knows, perhaps you&#39;ll find a time when this comes in handy. To me, it&#39;s helped give a more personal touch to my file organization, letting me do things my way rather than the way they came by default.&lt;/p&gt;
&lt;p&gt;Go forth and be awesome.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;In case it helps anyone, here&#39;s how my directories are configured, as of this writing:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOWNLOAD_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/downloads&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_LINKS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/links&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DOCUMENTS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/documents&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_WRITING_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/writing&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_MUSIC_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/music&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PODCAST_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/podcasts&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PICTURES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/pictures&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_SCREENSHOTS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/pictures/screenshots&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_VIDEOS_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/videos&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/templates&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_PUBLICSHARE_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/public&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_SCHOOL_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/school&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_NOTES_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/notes&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;XDG_DESKTOP_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/downloads&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, do you remember my &lt;a href=&quot;https://tty1.blog/articles/no-file-manager/#creating-files&quot;&gt;templates trick&lt;/a&gt; from the last article? That&#39;s a good use of &lt;code class=&quot;language-bash&quot;&gt;XDG_TEMPLATES_DIR&lt;/code&gt;.&lt;/p&gt;
&lt;/aside&gt;</content>
		<updated>2023-05-08T02:21:59.000Z</updated>
		<published>2023-05-08T02:21:59.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/no-file-manager/</id>
		<link href="https://tty1.blog/articles/no-file-manager/" rel="alternate"/>
		<title>You Don&#39;t Need a File Manager</title>
		<author>
			<name></name>
		</author>
		<summary>A file manager feels like an essential part of an operating system. In a blog where I talk largely about using terminal applications instead of GUIs, you might think I&#39;d spend this article exploring some terminal-based file managers.

Not so. Spare me a moment of your time, friend, and I will endeavour to illuminate why you, master of command-line secrets, have no need for such a petty thing as a &quot;file manager.&quot;</summary>
		<content type="html">&lt;p&gt;A file manager feels like an essential part of an operating system. In a blog where I talk largely about using terminal applications instead of GUIs, you might think I&#39;d spend this article exploring some terminal-based file managers.&lt;/p&gt;
&lt;p&gt;Not so. Spare me a moment of your time, friend, and I will endeavour to illuminate why you, master of command-line secrets, have no need for such a petty thing as a &amp;quot;file manager.&amp;quot;&lt;/p&gt;
&lt;h2 id=&quot;replacing-functionality&quot; tabindex=&quot;-1&quot;&gt;Replacing Functionality&lt;/h2&gt;
&lt;p&gt;Let&#39;s walk through the different things traditional file managers do and figure out new ways to do them with regular terminal commands.&lt;/p&gt;
&lt;h3 id=&quot;listing-files&quot; tabindex=&quot;-1&quot;&gt;Listing Files&lt;/h3&gt;
&lt;p&gt;If you know anything about the terminal, you should know this command. (If you don&#39;t, &lt;a href=&quot;https://tty1.blog/articles/anatomy-of-a-command/&quot;&gt;I pick it to pieces here&lt;/a&gt;.)&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;creating-files&quot; tabindex=&quot;-1&quot;&gt;Creating Files&lt;/h3&gt;
&lt;p&gt;If you want to create an empty text file, you can do this easily with &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; ~/notes/things-to-do-today.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To create a directory, use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; ~/notes/top-secret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If &lt;code class=&quot;language-bash&quot;&gt;~/notes&lt;/code&gt; doesn&#39;t already exist, this will throw an error. To create all necessary folders (and not just the final one), use the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--parents&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt;&lt;/code&gt; flag.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--parents&lt;/span&gt; ~/notes/top-secret
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; ~/notes/top-secret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&#39;re wanting to create files from templates, that&#39;s also pretty easy. First, create a folder to store your templates in.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; ~/templates
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whenever you have a new type of file you want to make a template for, create a file that&#39;s a starting point for the type in this &lt;code class=&quot;language-bash&quot;&gt;templates&lt;/code&gt; folder. Then, when you want to create a new file with that template, do it like so:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; ~/templates/tty1-post.md ./no-file-manager.md
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;opening-files&quot; tabindex=&quot;-1&quot;&gt;Opening Files&lt;/h3&gt;
&lt;p&gt;This one seems a bit tricky, but it&#39;s easy once you have it figured out. If you want to open a file in the default program, use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;xdg-open&lt;/span&gt;&lt;/code&gt;, from &lt;code class=&quot;language-bash&quot;&gt;xdg-utils&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;xdg-open&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;file&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Setting&lt;/em&gt; the default program for a file type is a bit trickier. &lt;code class=&quot;language-bash&quot;&gt;xdg-mime&lt;/code&gt; is the standard way to do so (see &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; xdg-mime&lt;/code&gt;), but I prefer to use a utility called &lt;a href=&quot;https://github.com/mbeijen/File-MimeInfo&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mimeopen&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ mimeopen &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filename&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you already have a program set to open the file in, it&#39;ll just open it. If not, it&#39;ll ask you to pick the program. If you want to force it to ask you even though you&#39;ve set the default application, use the &lt;code class=&quot;language-bash&quot;&gt;--ask-default&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt;&lt;/code&gt; flag:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ mimeopen --ask-default &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filename&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I set an alias for this to make it even easier:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mimeopen&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now running &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;file&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt; will open &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;file&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt; with the default program, asking which to use if you haven&#39;t set it.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;&lt;code class=&quot;language-bash&quot;&gt;mimeopen&lt;/code&gt; may or may not be easy for you to install depending on the Linux distribution you&#39;re using. It&#39;s been hit or miss for me.&lt;/p&gt;
&lt;p&gt;If you&#39;re up for &lt;a href=&quot;https://nixos.org/&quot;&gt;setting up nix&lt;/a&gt;, you can get &lt;code class=&quot;language-bash&quot;&gt;mimeopen&lt;/code&gt; from there even if your distro doesn&#39;t package it (the package is &lt;code class=&quot;language-bash&quot;&gt;perlPackages.FileMimeInfo&lt;/code&gt;). Or, if you prefer, build it yourself from source.&lt;/p&gt;
&lt;/aside&gt;
&lt;h3 id=&quot;moving-files&quot; tabindex=&quot;-1&quot;&gt;Moving Files&lt;/h3&gt;
&lt;p&gt;Moving files and directories is pretty easy.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/downloads/download.pdf ~/documents
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will move &lt;code class=&quot;language-bash&quot;&gt;download.pdf&lt;/code&gt; from &lt;code class=&quot;language-bash&quot;&gt;~/downloads&lt;/code&gt; to &lt;code class=&quot;language-bash&quot;&gt;~documents&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;renaming-files&quot; tabindex=&quot;-1&quot;&gt;Renaming Files&lt;/h3&gt;
&lt;p&gt;This solution is actually the same. You can use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt;&lt;/code&gt; to rename files and folders.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; untitled.md world-domination-plan.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can even move and rename at the same time:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; ~/downloads/untitled.md ~/notes/top-secret/world-domination-plan.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, you&#39;ll often want to rename multiple files in the same directory. There are a lot of tools for that, but I&#39;ve settled on &lt;code class=&quot;language-bash&quot;&gt;edir&lt;/code&gt;, myself.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;~/folder&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;$ edir 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will open a list of the files in the directory in my default text editor:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;	./untitled
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;	./untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;	./untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;	./untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;	./untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;	./untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;	./untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not very pretty, huh? Now that it&#39;s in my text editor, though, I can edit the names of any of those files here.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;	./cool-file
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;	./secret-plans
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;	./birthday-present-ideas
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;	./cookie-recipe
&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;	./ultimate-brownies
&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;	./short-story
&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;	./public-speaking-notes-03-31-2022
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I save and exit, &lt;code class=&quot;language-bash&quot;&gt;edir&lt;/code&gt; will apply the changes for me!&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;~/folder&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;$ edir
Renamed untitled to cool-file
Renamed untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; to secret-plans
Renamed untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; to birthday-present-ideas
Renamed untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; to cookie-recipe
Renamed untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; to ultimate-brownies
Renamed untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; to short-story
Renamed untitled &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; to public-speaking-notes-03-31-2022
~/folder&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;
birthday-present-ideas  cookie-recipe  cool-file  public-speaking-notes-03-31-2022  secret-plans  short-story  ultimate-brownies
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How helpful this is will depend partly on what text editor you use. For me, in &lt;code class=&quot;language-bash&quot;&gt;neovim&lt;/code&gt;, editing filenames this way is &lt;em&gt;far&lt;/em&gt; easier than repeatedly using &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;&lt;code class=&quot;language-bash&quot;&gt;edir&lt;/code&gt; may be packaged in your distribution, but if not it&#39;s available through &lt;code class=&quot;language-bash&quot;&gt;pipx&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ pipx &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; edir
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For more information see &lt;a href=&quot;https://github.com/bulletmark/edir&quot;&gt;its repository&lt;/a&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;h3 id=&quot;deleting-files&quot; tabindex=&quot;-1&quot;&gt;Deleting Files&lt;/h3&gt;
&lt;p&gt;Deleting files is easy.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; ~/unwanted-file.pdf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or delete all the files in a folder.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; ~/downloads/*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Deleting a directory is a little trickier. &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;rmdir&lt;/span&gt;&lt;/code&gt; will do the trick if it&#39;s empty.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;rmdir&lt;/span&gt; ~/junk-folder/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also use the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--parents&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt;&lt;/code&gt; flag, like in &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt;&lt;/code&gt;. However, if you want to remove a directory and everything in it, you&#39;ll need &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt;&lt;/code&gt; again, this time with the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--recursive&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt;&lt;/code&gt; flag.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--recursive&lt;/span&gt; ~/junk-folder/
&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
&lt;p&gt;I&#39;m gonna give you a quick tip right now: if anyone ever tells you to run &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rf&lt;/span&gt; /&lt;/code&gt; or any variant of it, &lt;strong&gt;&lt;em&gt;don&#39;t&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Now, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt;&lt;/code&gt; permanently deletes files. While this can be what you want, this isn&#39;t what a file manager usually does; it would move deleted files to the &amp;quot;trash.&amp;quot; Well, so can you, with &lt;a href=&quot;https://github.com/andreafrancia/trash-cli&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;trash-cli&lt;/code&gt;&lt;/a&gt;, a suite of commands to help you manage your trash!&lt;/p&gt;
&lt;p&gt;I&#39;m going to give some quick examples below, but for full instructions use the manpages for the commands.&lt;/p&gt;
&lt;h4 id=&quot;trash-files-or-folders&quot; tabindex=&quot;-1&quot;&gt;Trash files or folders&lt;/h4&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;trash &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
&lt;p&gt;I preferentially use this over &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt;&lt;/code&gt; because it works for files and directories, empty or no.&lt;/p&gt;
&lt;/aside&gt;
&lt;h4 id=&quot;empty-trash-older-than-days&quot; tabindex=&quot;-1&quot;&gt;Empty trash older than &lt;code class=&quot;language-bash&quot;&gt;days&lt;/code&gt;&lt;/h4&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;trash-empty &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;days&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&#39;ll want to do this fairly regularly or you won&#39;t be saving any storage space. I personally run &lt;code class=&quot;language-bash&quot;&gt;trash-empty &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;/code&gt; once every couple days.&lt;/p&gt;
&lt;h4 id=&quot;restore-trashed-files&quot; tabindex=&quot;-1&quot;&gt;Restore trashed files&lt;/h4&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;trash-restore
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will walk you through the process.&lt;/p&gt;
&lt;h2 id=&quot;advanced%3A-mounting-drives&quot; tabindex=&quot;-1&quot;&gt;Advanced: Mounting Drives&lt;/h2&gt;
&lt;p&gt;Now, I could go into the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt;&lt;/code&gt; command and how to use it, but if you want something that complex and nuanced, you can read &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt;&lt;/code&gt; yourself. &lt;a href=&quot;https://tty1.blog/articles/how-to-save-the-world-with-tar/&quot;&gt;I already went into a complicated command in-depth recently&lt;/a&gt; and I don&#39;t feel like doing it again here. (The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt;&lt;/code&gt; manpage is 80% longer than the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; manpage.)&lt;/p&gt;
&lt;p&gt;Instead, I&#39;d like to point you to &lt;code class=&quot;language-bash&quot;&gt;udisks2&lt;/code&gt;. It provides the handy &lt;code class=&quot;language-bash&quot;&gt;udisksctl&lt;/code&gt; utility.&lt;/p&gt;
&lt;p&gt;Once you have &lt;code class=&quot;language-bash&quot;&gt;udisks2&lt;/code&gt;, though, you have an even easier simpler solution: &lt;a href=&quot;https://github.com/coldfix/udiskie&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;udiskie&lt;/code&gt;&lt;/a&gt;. Install it, set it running, and any drives you attach will automatically be mounted to your filesystem. The result will be put in a folder depending on your distro; I&#39;ve seen &lt;code class=&quot;language-bash&quot;&gt;/media/&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your-username&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;/run/media/&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your-username&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt; as the base directory.&lt;/p&gt;
&lt;p&gt;Your desktop environment might already be set up to automatically mount drives, in which case you can ignore this section. If you&#39;re using a barebones window manager like me, though, this could come in handy.&lt;/p&gt;
&lt;h2 id=&quot;honorable-mentions%3A-terminal-based-file-managers&quot; tabindex=&quot;-1&quot;&gt;Honorable Mentions: Terminal-Based File Managers&lt;/h2&gt;
&lt;p&gt;Despite all this, there are some great terminal file managers out there. Here are some I&#39;ve heard of, in no particular order.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;vifm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;ranger&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;nnn&lt;/code&gt; (I have actually tried this one)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;lf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don&#39;t use any of these, so I don&#39;t make any guarantees of quality, but I have heard good things from people who do. Consider giving them a shot, but at least try to go terminal-only first; you have what it takes!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Surely by this point you have been convinced. You, discriminating command-line magician that you are, have no need for the crutch that a file manager is.&lt;/p&gt;
&lt;p&gt;Unleash your inner terminal nerd and manage your files with your terminal only! (At the very least, you&#39;ll get some sweet, sweet, nerd cred.) Go forth and be awesome.&lt;/p&gt;</content>
		<updated>2023-04-08T20:17:32.000Z</updated>
		<published>2023-04-08T20:17:32.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/how-to-save-the-world-with-tar/</id>
		<link href="https://tty1.blog/articles/how-to-save-the-world-with-tar/" rel="alternate"/>
		<title>How to Save the World with tar</title>
		<author>
			<name></name>
		</author>
		<summary>While there are hundreds of difficult-to-understand commands out there, few have acquired the *notoriety* of `tar`. Most guides are filled with abstruse commands such as `tar -czvf archive.tar.gz ~/Downloads/` with little to no explanation. Based on conversations I&#39;ve had, people who interact with `tar` tend to just memorize a basic command or too, like `tar -xvf &lt;filename&gt;` and hope for the best.

Let&#39;s take a closer look at `tar` and learn how it actually works.</summary>
		<content type="html">&lt;p&gt;While there are hundreds of difficult-to-understand commands out there, few have acquired the &lt;em&gt;notoriety&lt;/em&gt; of &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt;. Most guides are filled with abstruse commands such as &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-czvf&lt;/span&gt; archive.tar.gz ~/Downloads/&lt;/code&gt; with little to no explanation. Based on conversations I&#39;ve had, people who interact with &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; tend to just memorize a basic command or two, like &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xvf&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filename&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt; and hope for the best.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;xkcd#1168; full transcript at https://explainxkcd.com/1168/&quot; src=&quot;https://imgs.xkcd.com/comics/tar.png&quot; title=&quot;I don&#39;t know what&#39;s worse--the fact that after 15 years of using tar I still can&#39;t keep the flags straight, or that after 15 years of technological advancement I&#39;m still mucking with tar flags that were 15 years old when I started.&quot;&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;a href=&quot;https://xkcd.com/1168/&quot;&gt;xkcd#1168&lt;/a&gt; by Randall Munroe&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Let&#39;s take a closer look at &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; and learn how it actually works.&lt;/p&gt;
&lt;h2 id=&quot;a-quick-summary&quot; tabindex=&quot;-1&quot;&gt;A Quick Summary&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; is used for creating and interacting with archive files; &lt;code class=&quot;language-bash&quot;&gt;.tar&lt;/code&gt; archive are similar in functionality to &lt;code class=&quot;language-bash&quot;&gt;.zip&lt;/code&gt; files, which you may be more familiar with.&lt;/p&gt;
&lt;p&gt;The name &amp;quot;tar&amp;quot; is short for &amp;quot;tape archives&amp;quot;; the original idea behind tar is that the archives in question would be stored on tape. In contemporary usage, that&#39;s not usually the case.&lt;/p&gt;
&lt;h2 id=&quot;the-%22easy%22-way-to-learn&quot; tabindex=&quot;-1&quot;&gt;The &amp;quot;Easy&amp;quot; Way to Learn&lt;/h2&gt;
&lt;p&gt;The best explanation of &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; is in its manual page.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt;&lt;/code&gt; page is extremely long and most people skip it altogether. Still, if you want a deeper understanding than what this guide will give you, the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt;&lt;/code&gt; page is the place to go.&lt;/p&gt;
&lt;h2 id=&quot;usage-styles&quot; tabindex=&quot;-1&quot;&gt;Usage Styles&lt;/h2&gt;
&lt;h3 id=&quot;%22traditional%22-usage&quot; tabindex=&quot;-1&quot;&gt;&amp;quot;Traditional&amp;quot; Usage&lt;/h3&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; xvf archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I won&#39;t cover this style in this article. Most of the basics are similar to Unix-style flags, and any other information you need to know is explained within &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; under &lt;code class=&quot;language-bash&quot;&gt;Description ⇒ Option Styles&lt;/code&gt;. It&#39;s not the style I recommend you use, but it may be handy to understand if you see it in another guide.&lt;/p&gt;
&lt;h3 id=&quot;%22unix-style%22-usage&quot; tabindex=&quot;-1&quot;&gt;&amp;quot;Unix-style&amp;quot; Usage&lt;/h3&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xvf&lt;/span&gt; archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are standard &lt;a href=&quot;https://tty1.blog/articles/anatomy-of-a-command/#--almost-all---sortextension---the-flags&quot;&gt;short flags&lt;/a&gt;; you can use them individually (&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-x&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt;) or combine them (&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-xvf&lt;/span&gt;&lt;/code&gt;). This is the form you&#39;ll usually see used.&lt;/p&gt;
&lt;h3 id=&quot;%22gnu-style%22-usage&quot; tabindex=&quot;-1&quot;&gt;&amp;quot;GNU-style&amp;quot; Usage&lt;/h3&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--extract&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think this is the most straightforward way to use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt;; it&#39;s much clearer what the different flags mean and which arguments are passed to which flags. However, it&#39;s much harder to type out, so it isn&#39;t usually used.&lt;/p&gt;
&lt;p&gt;Something many people don&#39;t know, though, is that you don&#39;t have to type out the full flags; you can just use the first letters, as long as the letters you type are unique to one flag.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--ext&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--verbo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you shorten a flag too far and there are multiple possibilities, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; will warn you and give you the possible completions.&lt;/p&gt;
&lt;h2 id=&quot;flag-walkthrough&quot; tabindex=&quot;-1&quot;&gt;Flag Walkthrough&lt;/h2&gt;
&lt;p&gt;Let&#39;s go through some of the most useful flags one by one and learn how they&#39;re used.&lt;/p&gt;
&lt;h3 id=&quot;--verbose%2F-v&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;&lt;/code&gt; flag just makes sure that you&#39;ll see all output from the command you run; by default, most &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; commands will just do everything without returning any output, making it hard to tell if anything is happening, especially when a command takes a long time to run.&lt;/p&gt;
&lt;p&gt;As a general rule, I add &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;&lt;/code&gt; to almost every &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; command I run; I like seeing what&#39;s going on. It will, though, spit out a &lt;em&gt;ton&lt;/em&gt; of information, filling up your terminal screen, which might not be what you want.&lt;/p&gt;
&lt;h3 id=&quot;--extract%2F-x&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--extract&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-x&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This flag says to extract the contents of an archive; you&#39;ll need to use the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;/code&gt; flag for it to do anything, which we&#39;ll learn about next.&lt;/p&gt;
&lt;p&gt;Optionally, it takes arguments to specify &lt;em&gt;which&lt;/em&gt; files to extract.&lt;/p&gt;
&lt;h3 id=&quot;--file%2F-f&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This flag specifies the archive file that you&#39;ll be working with, whether you&#39;re creating it, reading from it, adding files, etc. It takes one argument, the location of the archive file.&lt;/p&gt;
&lt;p&gt;This is a good time to talk about how to pass arguments in &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt;. The long flags are the easiest to pass to:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--extract&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use a space instead of the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;/code&gt;, but I suggest you use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;/code&gt; for clarity.&lt;/p&gt;
&lt;p&gt;For short flags, the argument value must follow the flag it&#39;s being passed to. This can take multiple forms:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; archive.tar.gz &lt;span class=&quot;token parameter variable&quot;&gt;-xv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xvf&lt;/span&gt; archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;--list%2F-t&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--list&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This flag says to list everything in an archive specified by &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;/code&gt; or &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--list&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-tf&lt;/span&gt; archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don&#39;t generally bother including &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;&lt;/code&gt; with this, since it&#39;ll be outputting the contents of the archive anyway.&lt;/p&gt;
&lt;p&gt;Optionally, this takes arguments to specify which files to list.&lt;/p&gt;
&lt;h3 id=&quot;--create%2F-c&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--create&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This flag says to create a new &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; archive with the filename and location specified by &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt; or &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;/code&gt;. It takes one or multiple arguments to specify which files to add to the new archive.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--create&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=~&lt;/span&gt;/school &lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;school.tar &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--create&lt;/span&gt; ~/school ~/Downloads ~/writing &lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;archive.tar &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-cvf&lt;/span&gt; archive.tar ~/projects
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that arguments passed to the action flag (such as &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt;&lt;/code&gt;, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt;&lt;/code&gt;, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-x&lt;/span&gt;&lt;/code&gt;) can be put at the end of the command, after all the other flags, as shown in the last example above. I couldn&#39;t find any specific rationale for that in the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; manpage, but it works and people often do it that way.&lt;/p&gt;
&lt;h3 id=&quot;--gzip%2F-z&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--gzip&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-z&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--create&lt;/span&gt;&lt;/code&gt; alone doesn&#39;t apply any compression to files; to do that, you need to select a compression method. I personally always use gzip, which is applied with the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--gzip&lt;/span&gt;&lt;/code&gt; or &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-z&lt;/span&gt;&lt;/code&gt; flag.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-czvf&lt;/span&gt; archive.tar.gz ~/Downloads
&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
&lt;p&gt;Why not always do this? Well, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; takes a significant performance hit when applying compression, and it doesn&#39;t always save much space.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;To use a different compression type, swap out this flag for the flag of the type you want to use. By convention, an extra file extension is appended to compressed archives, depending on the type of compression.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--gzip&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-z&lt;/span&gt;&lt;/code&gt; - &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;gzip&lt;/span&gt;&lt;/code&gt; compression, uses &lt;code class=&quot;language-bash&quot;&gt;.tar.gz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--bzip2&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-j&lt;/span&gt;&lt;/code&gt; - &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bzip2&lt;/span&gt;&lt;/code&gt; compression, uses &lt;code class=&quot;language-bash&quot;&gt;.tar.bz2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--xz&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-J&lt;/span&gt;&lt;/code&gt; - &lt;code class=&quot;language-bash&quot;&gt;xz&lt;/code&gt; compression, uses &lt;code class=&quot;language-bash&quot;&gt;.tar.xz&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some others too, but you get the idea. See &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; for a full list of compression methods.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;There&#39;s another way to do compression that you might find easier; use &lt;code class=&quot;language-bash&quot;&gt;--auto-compress&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt;&lt;/code&gt; to automatically detect how to compress the file based on the filename you chose. For example:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-cavf&lt;/span&gt; archive.tar.xz ~/Downloads
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will notice the &lt;code class=&quot;language-bash&quot;&gt;.tar.xz&lt;/code&gt; ending to the archive name and automatically use &lt;code class=&quot;language-bash&quot;&gt;xz&lt;/code&gt; compression.&lt;/p&gt;
&lt;/aside&gt;
&lt;h3 id=&quot;--append%2F-r&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--append&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This will add files to an archive. Use it the same way you would &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--create&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt;&lt;/code&gt;; use &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--file&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt; to specify the archive, then pass directory and file paths to it to have them added to the archive.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rvf&lt;/span&gt; school.tar.gz ~/Downloads/syllabus.pdf
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;more&quot; tabindex=&quot;-1&quot;&gt;More&lt;/h3&gt;
&lt;p&gt;There are &lt;em&gt;many&lt;/em&gt; other flags for &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt;, some of which may be useful to you. The goal of this article was largely to get you to the point where reading the manual page will actually be helpful rather than just daunting. If you need to do something you don&#39;t know how to with &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt;, here&#39;s what I&#39;d recommend:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Begin by searching up what you want to do and finding a guide for it. Unfortunately, most guides to &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; aren&#39;t very conducive to actually &lt;em&gt;understanding&lt;/em&gt; what you&#39;re doing, just rote memorization.&lt;/li&gt;
&lt;li&gt;Take any flags you don&#39;t understand from what you find and look for them in &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; to get full instructions for how to use them. The manpage is actually pretty helpful if you&#39;re just looking up flags with a basic preexisting knowledge of how &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; works.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;practice&quot; tabindex=&quot;-1&quot;&gt;Practice&lt;/h2&gt;
&lt;p&gt;Let&#39;s try this out; I&#39;ll begin by giving you some example commands with &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; (using short flags, since the long ones are pretty easy). See if you can figure out what they do, then look at the explanation to test your knowledge.&lt;/p&gt;
&lt;hr&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xvf&lt;/span&gt; archive.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;details&gt;&lt;summary&gt;Show Explanation&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-x&lt;/span&gt;&lt;/code&gt; - this is the action; this command will be extracting all contents of an archive (since specific contents were not passed to the argument)&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;&lt;/code&gt; - the command will be spitting out extra information as a status report&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt; - this gets passed the archive we&#39;re working with; in this case, &lt;code class=&quot;language-bash&quot;&gt;archive.tar.gz&lt;/code&gt; is the archive. (Note that it is compressed using gzip.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The final result? The archive gets decompressed to the current directory. If you&#39;re going to remember one &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; command, this is a good one; it will always extract the archive you specify, regardless of compression.&lt;/p&gt;
&lt;/details&gt;
&lt;hr&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xvwf&lt;/span&gt; archive.tar
&lt;/code&gt;&lt;/pre&gt;
&lt;details&gt;&lt;summary&gt;Show Hint&lt;/summary&gt;
&lt;p&gt;You&#39;re going to need to test your manpage-searching skills for this one!&lt;/p&gt;
&lt;/details&gt;
&lt;details&gt;&lt;summary&gt;Show Explanation&lt;/summary&gt;
&lt;p&gt;This is &lt;em&gt;almost&lt;/em&gt; the same as the last one; the only difference is the added &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-w&lt;/span&gt;&lt;/code&gt; flag. If you checked &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt;, you know that this flag means that &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; will ask for individual confirmation before extracting each file.&lt;/p&gt;
&lt;/details&gt;
&lt;hr&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-cavf&lt;/span&gt; backup.tar.gz ~/Documents
&lt;/code&gt;&lt;/pre&gt;
&lt;details&gt;&lt;summary&gt;Show Explanation&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt;&lt;/code&gt; - creates an archive&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt;&lt;/code&gt; - automatically detects what compression to use based on the filename of the archive&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt;&lt;/code&gt; - use verbose output&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt;&lt;/code&gt; - sets the filename for the archive, &lt;code class=&quot;language-bash&quot;&gt;backup.tar.gz&lt;/code&gt;—note that this will make the archive use gzip compression, due to the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-a&lt;/span&gt;&lt;/code&gt; flag and the file extension &lt;code class=&quot;language-bash&quot;&gt;.tar.gz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/Documents&lt;/code&gt; - Makes &lt;code class=&quot;language-bash&quot;&gt;~/Documents&lt;/code&gt; the content of the new archive&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Congratulations, you know enough about &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt;&lt;/code&gt; to save the world from nuclear destruction! Go forth and use your newfound knowledge for good, not evil. (Or, you know, if you want to use it for evil, that&#39;s up to you, I suppose.)&lt;/p&gt;
&lt;p&gt;See you next time; we&#39;ll be considering whether file managers are &lt;em&gt;really&lt;/em&gt; necessary.&lt;/p&gt;</content>
		<updated>2023-03-31T23:13:41.000Z</updated>
		<published>2023-03-31T23:13:41.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/anatomy-of-a-command/</id>
		<link href="https://tty1.blog/articles/anatomy-of-a-command/" rel="alternate"/>
		<title>Anatomy of a Command</title>
		<author>
			<name></name>
		</author>
		<summary>For the most part, this blog will not be dealing with the very basics. I find it safe to assume that most people interested in a blog about the Linux terminal already have some degree of fundamental knowledge about it.

That said, it&#39;s a good idea to have a grounding place we can all start off from. Let&#39;s take a command and dissect it, looking at its parts and learning what they mean.</summary>
		<content type="html">&lt;p&gt;For the most part, this blog will not be dealing with the very basics. I find it safe to assume that most people interested in a blog about the Linux terminal already have some degree of fundamental knowledge about it.&lt;/p&gt;
&lt;p&gt;That said, it&#39;s a good idea to have a grounding place we can all start off from. Let&#39;s take a command and dissect it, looking at its parts and learning what they mean.&lt;/p&gt;
&lt;h2 id=&quot;anatomy-of-a-command&quot; tabindex=&quot;-1&quot;&gt;Anatomy of a Command&lt;/h2&gt;
&lt;p&gt;Lets start off with this simple command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; --almost-all &lt;span class=&quot;token parameter variable&quot;&gt;--sort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;extension ~/downloads
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whoa, whoa, whoa, what&#39;s going on here? So much. If you&#39;re not very used to the terminal, this is a perplexing line of gibberish. Let&#39;s break it down.&lt;/p&gt;
&lt;h3 id=&quot;%24---the-prompt&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$&lt;/code&gt; - The Prompt&lt;/h3&gt;
&lt;p&gt;See the &lt;code class=&quot;language-bash&quot;&gt;$&lt;/code&gt; at the beginning of the line? That&#39;s what&#39;s known as the shell &amp;quot;prompt.&amp;quot; Prompts come in all different flavors, but there&#39;s one thing that remains consistent between most default prompts, by convention:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If it ends in &lt;code class=&quot;language-bash&quot;&gt;$&lt;/code&gt;, any commands are being run by a normal user&lt;/li&gt;
&lt;li&gt;If it ends in &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;&lt;/code&gt;, any commands are being run by the &lt;code class=&quot;language-bash&quot;&gt;root&lt;/code&gt; (or administrator) user&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usually, your prompt will be more complex, something more like this:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;benjamin@archimedes:~/projects/tty1.blog&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A quick rundown of what&#39;s going on here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;benjamin&lt;/code&gt; - my username&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;archimedes&lt;/code&gt; - the &amp;quot;hostname&amp;quot;, or name of the computer I&#39;m using&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;~/projects/tty1.blog&lt;/code&gt; - the path to the &amp;quot;working directory&amp;quot;, the current folder I&#39;m inside. Commands run will by default be performed in this folder.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Basically, a prompt is meant to give you information to help contextualize commands you run.&lt;/p&gt;
&lt;p&gt;For tty1, I will use the following convention:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For most commands, I&#39;ll use a simple &lt;code class=&quot;language-bash&quot;&gt;$&lt;/code&gt; or &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If it matters what directory I&#39;m in, I&#39;ll use &lt;code class=&quot;language-bash&quot;&gt;path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;/code&gt; or &lt;code class=&quot;language-bash&quot;&gt;path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;&lt;/code&gt;. For example, &lt;code class=&quot;language-bash&quot;&gt;~/projects/tty1.blog&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; $&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keep in mind: the prompt is not part of the command you run. If you&#39;re copying a command, &lt;em&gt;don&#39;t include the starting &lt;code class=&quot;language-bash&quot;&gt;$&lt;/code&gt; in what you run or you&#39;ll get an error&lt;/em&gt;.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;To be clear: it&#39;s a bad idea to copy/paste a command into your terminal. Type it out yourself, and only if you know &lt;em&gt;exactly&lt;/em&gt; what it does. A malicious command can do anything it wants to your system, which is not good&lt;sup&gt;[&lt;a href=&quot;https://xkcd.com/285/&quot;&gt;citation needed&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;h3 id=&quot;ls---the-command&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt; - The Command&lt;/h3&gt;
&lt;p&gt;While the whole line you enter in is often referred to as a command, the actual command itself is just the program being run. In this case, that&#39;s &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt;, a command which lists files and directories in a directory (&amp;quot;directory&amp;quot; is what most people know as a folder).&lt;/p&gt;
&lt;h3 id=&quot;~%2Fdownloads---arguments&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;~/downloads&lt;/code&gt; - Arguments&lt;/h3&gt;
&lt;p&gt;An &amp;quot;argument&amp;quot; is a piece of information you give to a command to help it do its job. Each command will take a certain number of arguments; &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt; takes one, the path.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;See the &lt;code class=&quot;language-bash&quot;&gt;~&lt;/code&gt; character? That&#39;s a special nickname for your &amp;quot;home directory&amp;quot;, the folder while all of your files are.&lt;/p&gt;
&lt;p&gt;Usually, your home directory will be at &lt;code class=&quot;language-bash&quot;&gt;/home/username&lt;/code&gt;; in my case, that&#39;s &lt;code class=&quot;language-bash&quot;&gt;/home/benjamin&lt;/code&gt;, so for me, &lt;code class=&quot;language-bash&quot;&gt;~/downloads&lt;/code&gt; expands to &lt;code class=&quot;language-bash&quot;&gt;/home/benjamin/downloads&lt;/code&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Giving a command an argument is called &amp;quot;passing&amp;quot; it the argument. By passing &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt; (which lists the files and directories in a directory) the &lt;code class=&quot;language-bash&quot;&gt;~/downloads&lt;/code&gt; path, you&#39;re telling it to list for you every file and directory inside the &lt;code class=&quot;language-bash&quot;&gt;~/downloads&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;For ls, this argument is optional; if you&#39;d left it out, by default it would assume you want a list of the files in the folder you&#39;re currently inside, the &amp;quot;working directory&amp;quot;.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;Confused? I&#39;ll show you later in this article how to learn a command&#39;s arguments if you don&#39;t know them already.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Commands will sometimes have multiple arguments, in which case they&#39;re separated by spaces.&lt;/p&gt;
&lt;h3 id=&quot;--almost-all---sort%3Dextension---the-flags&quot; tabindex=&quot;-1&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;--almost-all &lt;span class=&quot;token parameter variable&quot;&gt;--sort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;extension&lt;/code&gt; - The Flags&lt;/h3&gt;
&lt;p&gt;Flags specify options or settings to use when running the command. In this case:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;--almost-all&lt;/code&gt; means to show all files and folders, including ones that would normally be hidden (files and folders starting with &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt; are hidden by default), but excluding &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt; (referring to the directory itself) and &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;&lt;/code&gt; (referring to the parent directory).&lt;/li&gt;
&lt;li&gt;By default, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt; will sort the results alphabetically. Using &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--sort&lt;/span&gt;&lt;/code&gt;, you can tell it to sort a different way. Some flags, like &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--sort&lt;/span&gt;&lt;/code&gt;, allow or require you to pass arguments to them, like you would with commands. Unfortunately, different commands will often have different ways to do this.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Confused yet? There&#39;s more. Most programs have multiple versions of each flag. While each command can do this differently, usually flags starting with &lt;code class=&quot;language-bash&quot;&gt;--&lt;/code&gt; are &amp;quot;long&amp;quot; flags and ones starting with &lt;code class=&quot;language-bash&quot;&gt;-&lt;/code&gt; are short ones which are easier to type out. For example, in the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt; command, &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-A&lt;/span&gt;&lt;/code&gt; means &lt;code class=&quot;language-bash&quot;&gt;--almost-all&lt;/code&gt; and &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt;&lt;/code&gt; means &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--sort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;extension&lt;/code&gt;. With that in mind, we could have written our command this way:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-A&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; ~/downloads
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In fact, you can go even shorter. With one-letter short flags, you can combine them like so:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-AX&lt;/span&gt; ~/downloads
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That means the same thing as our original command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; --almost-all &lt;span class=&quot;token parameter variable&quot;&gt;--sort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;extension ~/downloads
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While short flags are far quicker to type out, I&#39;ll avoid using them in this blog, since they&#39;re confusing and less understandable than long flags if you don&#39;t know what&#39;s going on.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;If you want to pass an argument to a flag, I recommend you use the long version; usually, you&#39;ll do that with an equals sign, like above (and if not, just use a space instead of the equals sign). With the short version, it&#39;s far more confusing and will sometimes change depending on the command.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Options should be listed before the arguments of the command.&lt;/p&gt;
&lt;h2 id=&quot;getting-help&quot; tabindex=&quot;-1&quot;&gt;Getting Help&lt;/h2&gt;
&lt;p&gt;You know how commands work! Well, you know the basics. You&#39;re almost certainly going to run into problems and issues, especially since I won&#39;t usually be sticking to the basics like I do in this article. Here are some resources that can help with that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt;&lt;/code&gt; - gives manual pages for commands. &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt;, for example, has a full explanation of how to use the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt;&lt;/code&gt; command, including its flags and arguments. This is the most comprehensive way to learn about commands you aren&#39;t familiar with, but can sometimes be intimidating. A good way to get started with it and learn how it works is to run &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt;&lt;/code&gt; and read the result.
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-bash&quot;&gt;tldr&lt;/code&gt; is a &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt;&lt;/code&gt; alternative that simplifies the instructions and gives you a few basic examples. See &lt;a href=&quot;https://tldr.sh/&quot;&gt;tldr.sh&lt;/a&gt; for more information. This is excellent for quick reference, but tends to oversimplify and may not know about every command you want to use. (You&#39;ll need to install &lt;code class=&quot;language-bash&quot;&gt;tldr&lt;/code&gt;; it doesn&#39;t usually come installed on your system.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://wiki.archlinux.org/&quot;&gt;ArchWiki&lt;/a&gt; is an excellent source of information about anything to do with Linux, even if you&#39;re not on Arch (btw)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask people for help.&lt;/strong&gt; Other people are your best bet if you&#39;re stuck; many of us have gone through the same issues. If you&#39;d like to ask me, &lt;a href=&quot;https://fosstodon.org/@benjaminhollon&quot;&gt;I&#39;m active on Mastodon&lt;/a&gt; or you can &lt;a href=&quot;https://benjaminhollon.com/contact/&quot;&gt;contact me directly&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</content>
		<updated>2023-03-25T19:26:31.000Z</updated>
		<published>2023-03-25T19:26:31.000Z</published>
	</entry>
	
	<entry>
		<id>https://tty1.blog/articles/introduction/</id>
		<link href="https://tty1.blog/articles/introduction/" rel="alternate"/>
		<title>Introduction</title>
		<author>
			<name></name>
		</author>
		<summary>Welcome to tty1, a blog about the Linux terminal! Get started on your journey with this article.</summary>
		<content type="html">&lt;p&gt;Welcome to tty1, a blog about the Linux terminal!&lt;/p&gt;
&lt;h2 id=&quot;who-are-you%2C-and-what-is-this-all-about%3F&quot; tabindex=&quot;-1&quot;&gt;Who are you, and what is this all about?&lt;/h2&gt;
&lt;p&gt;Easy to answer the first question:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;whoami&lt;/span&gt;
benjamin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I kid. Let me introduce myself for real.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; about-&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whoami&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.toml
name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Benjamin Hollon&quot;&lt;/span&gt;

website &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;benjaminhollon.com&quot;&lt;/span&gt;
code &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;codeberg.org/benjaminhollon&quot;&lt;/span&gt;
mastodon &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@benjaminhollon@fosstodon.org&quot;&lt;/span&gt;

occupation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;university student&quot;&lt;/span&gt;
major &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Communications (BA)&quot;&lt;/span&gt;
university &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Texas A&amp;amp;M&quot;&lt;/span&gt;

hobbies &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;writing&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;coding&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;astronomy&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;playing trombone&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;composing music&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;reading&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
dream &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;developing and supporting Free and Open Source software for the writing industry&quot;&lt;/span&gt;
terminal_emulator_of_choice &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;foot&quot;&lt;/span&gt;

citizenship &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;United States of America&quot;&lt;/span&gt;
lived &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;Afghanistan&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;India&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;Malaysia&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;United States of America&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is this a nerdy way to introduce myself? Yes. If that&#39;s not what you&#39;re looking for, I&#39;m sorry to burst your bubble, but you&#39;re in the wrong place. This is a nerdy blog for nerdy people.&lt;/p&gt;
&lt;p&gt;As for what this is about, tty1 is a blog where I&#39;ll share tips, tricks, guides, reviews, and anything and everything related to the Linux terminal. If you don&#39;t know what that means, again, you&#39;re in the wrong place.&lt;/p&gt;
&lt;p&gt;Eventually, this blog may feature &lt;a href=&quot;https://tty1.blog/guest-authors/&quot;&gt;guest articles&lt;/a&gt; by people who know their stuff; we&#39;ll be starting off with articles by yours truly as I get into stride and establish the proper tone and feel for this blog.&lt;/p&gt;
&lt;h3 id=&quot;why-the-name-tty1%3F&quot; tabindex=&quot;-1&quot;&gt;Why the name &lt;code class=&quot;language-bash&quot;&gt;tty1&lt;/code&gt;?&lt;/h3&gt;
&lt;p&gt;Long story short, a &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tty&lt;/span&gt;&lt;/code&gt; is a terminal for your Linux-based operating system that doesn&#39;t require a graphical system like X or Wayland.&lt;/p&gt;
&lt;p&gt;Originally, I was going to write this blog about my attempt to daily-drive a Linux installation without a graphical system, doing everything from the &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;tty&lt;/span&gt;&lt;/code&gt;, hence the title. I&#39;ve since broadened it to be about the Linux terminal in general, but the name still fits.&lt;/p&gt;
&lt;h2 id=&quot;housekeeping&quot; tabindex=&quot;-1&quot;&gt;Housekeeping&lt;/h2&gt;
&lt;p&gt;Let&#39;s get a few things straight before we begin our grand tour of the Linux terminal.&lt;/p&gt;
&lt;h3 id=&quot;subscribing-for-updates&quot; tabindex=&quot;-1&quot;&gt;Subscribing for updates&lt;/h3&gt;
&lt;p&gt;To get updates, you can use a feed reader, subscribing to the link &lt;a href=&quot;https://tty1.blog/feed/&quot;&gt;https://tty1.blog/feed/&lt;/a&gt; for the tty1 Atom Feed. You can also open the link to see a preview of the feed. For an explanation of what Atom Feeds are, check out &lt;a href=&quot;https://aboutfeeds.com/&quot;&gt;About Feeds&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For a good terminal client to check your RSS feeds, I highly recommend &lt;a href=&quot;https://newsboat.org/&quot;&gt;newsboat&lt;/a&gt;. That&#39;s the client I use. The website has a comprehensive guide and of course you can always run &lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;man&lt;/span&gt; newsboat&lt;/code&gt; to get information on using it.&lt;/p&gt;
&lt;h3 id=&quot;contacting-me&quot; tabindex=&quot;-1&quot;&gt;Contacting Me&lt;/h3&gt;
&lt;p&gt;There are &lt;a href=&quot;https://benjaminhollon.com/contact/&quot;&gt;a few ways to contact me&lt;/a&gt; on my site, but if you&#39;re not wanting a private conversation (in which case email is best), I&#39;d love if you reach out to me on &lt;a href=&quot;https://fosstodon.org/@benjaminhollon&quot;&gt;Mastodon&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;I&#39;m happy to take feedback, topic recommendations, questions, cookie recipes, and anything else on your mind.&lt;/p&gt;
&lt;h3 id=&quot;why-the-%22linux%22-terminal%3F&quot; tabindex=&quot;-1&quot;&gt;Why the &amp;quot;Linux&amp;quot; terminal?&lt;/h3&gt;
&lt;p&gt;Other operating systems may have great terminals, but I use Linux. Some of what I talk about will apply to other operating systems, but I&#39;m not going to make any guarantees; do your own research to make sure.&lt;/p&gt;
&lt;h2 id=&quot;thank-you!&quot; tabindex=&quot;-1&quot;&gt;Thank you!&lt;/h2&gt;
&lt;p&gt;With all of this out of the way, we&#39;ll be kicking this blog off with a deep dive into the anatomy of a command.&lt;/p&gt;</content>
		<updated>2023-03-24T14:35:57.000Z</updated>
		<published>2023-03-24T14:35:57.000Z</published>
	</entry>
	
</feed>
