<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jon Ericson</title>
    <description>The latest articles on DEV Community by Jon Ericson (@jericson).</description>
    <link>https://dev.to/jericson</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F186068%2F82c6a531-020a-4ab0-bb4e-093f19563d51.jpeg</url>
      <title>DEV Community: Jon Ericson</title>
      <link>https://dev.to/jericson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jericson"/>
    <language>en</language>
    <item>
      <title>Installing PostgreSQL the hard way</title>
      <dc:creator>Jon Ericson</dc:creator>
      <pubDate>Fri, 14 May 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/jericson/installing-postgresql-the-hard-way-2bc3</link>
      <guid>https://dev.to/jericson/installing-postgresql-the-hard-way-2bc3</guid>
      <description>&lt;p&gt;Since &lt;a href="///2021/04/30/developer_advocate.html"&gt;I joined EDB&lt;/a&gt;, I figured it was time to learn how to install Postgres. I techinically did it when I &lt;a href="///2021/04/06/oracle_discourse.html"&gt;installed Discourse&lt;/a&gt;. And at some point I seem to have typed &lt;code&gt;brew intstall postgres&lt;/code&gt; on my MacBook. But I'm talking installing it the hard way. I'm talking &lt;a href="https://www.postgresql.org/docs/current/installation.html"&gt;installing from the source code&lt;/a&gt;. Yeah!&lt;/p&gt;

&lt;p&gt;I've always found that the only way to learn new technology is to have a reason to use it. Work-related requirements suffice, but it's even better to have a hobby-related reason. For example, &lt;a href="https://billpetti.github.io/2019-08-10-build-retrosheet-event-roster-database-rstats-baseballr/"&gt;creating a baseball database&lt;/a&gt;. If you want to do research on baseball history, a great place to start is&lt;a href="https://www.retrosheet.org/site"&gt;Project Retrosheet&lt;/a&gt; which has detailed play-by-play files going back to 1916. So if you load this data into a database, you can do all sorts of queries to find out how often (or even whether) certain events have happened. For instance, has anyone ever hit two grand slams in an inning?&lt;sup&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;The instructions for installing Postgres and for setting up a Retrosheet database are incomplete for a very simple reason: prerequisites. People who have correctly set up their environment already have everything they needed. People who are getting started don't know what they are missing. Critically, it takes a lot of effort to figure out which of the many possible prerequisites are actually required. So what's needed is either someone to start from scratch and document everything they needed to install.&lt;/p&gt;

&lt;p&gt;I got a PC for my new job and this is the first time in nearly a decade that I've used Windows in earnest. So I have some adjustments to make. I started documenting them &lt;a href="https://gist.github.com/jericson/b4f8199b24f7265f818a843a9a114b24"&gt;over here&lt;/a&gt;, but I have a feeling this list will grow over time.&lt;sup&gt;2&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;One of the reasons I'm documenting these steps is that I'm going back and testing the installation process using a pristine &lt;a href="https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/quick-create-virtual-machine"&gt;Windows virtual machine&lt;/a&gt;. That way I can test what things are really needed and what is optional or unnecessary. Or, at least I could in theory and maybe will in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Retrosheet data
&lt;/h2&gt;

&lt;p&gt;Retrosheet's data has an idiosyncratic format, so it helps to have software to parse it. So the next step is to download the&lt;a href="http://chadwick.sourceforge.net/doc/cwtools.html"&gt;command-line tools&lt;/a&gt;maintained by the &lt;a href="http://chadwick-bureau.com/"&gt;Chadwick Baseball Bureau&lt;/a&gt;. Then I move them to&lt;code&gt;C:\Users\[username]\bin&lt;/code&gt; and add that to my PATH environment variable. That way I can use those executables without specifying the full path. More importantly, so can R scripts.&lt;/p&gt;

&lt;p&gt;Since the instructions I'm following use R, the next step is to&lt;a href="https://cran.rstudio.com/"&gt;download a recent version of R&lt;/a&gt;. While not strictly necessary, I also grabbed&lt;a href="https://www.rstudio.com/products/rstudio/download/"&gt;RStudio&lt;/a&gt;, which is a fantastic IDE that uses &lt;a href="https://rmarkdown.rstudio.com/"&gt;R Markdown&lt;/a&gt;. It's a form of &lt;a href="https://en.wikipedia.org/wiki/Literate_programming"&gt;literate programming&lt;/a&gt; that allows both a data-centric article and the script that generated the data to live in the same document.&lt;sup&gt;3&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Next you gotta install a bunch of R libraries the script need. Start with&lt;a href="https://www.r-project.org/nosvn/pandoc/devtools.html"&gt;&lt;code&gt;devtools&lt;/code&gt;&lt;/a&gt; and then run the following commands from the RStudio console window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install.packages("devtools")
install.packages('h2o')
install.packages('emayili')
install_github("BillPetti/bpettir")
install.packages("purrr")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I made a few tweaks to the script Bill Petti uses to parse and load Retrosheet data. One problem is that several packages must be loaded first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require(bpettir)
require(future)
require(furrr)
require(purrr)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can go at the top of the script where the other &lt;code&gt;require&lt;/code&gt;statements live for simplicity. I also changed &lt;code&gt;"~/Desktop/retrosheet"&lt;/code&gt; to &lt;code&gt;"~/retrosheet"&lt;/code&gt; and added &lt;code&gt;setwd&lt;/code&gt; commands to make sure the script is in the right directory for each input file it needs. For some reason, RStudio actually puts its output in&lt;code&gt;~/Documents/retrosheet&lt;/code&gt;. I think it uses a&lt;a href="https://en.wikipedia.org/wiki/Sandbox_(computer_security)"&gt;sandbox&lt;/a&gt; for R that has &lt;code&gt;~/Documents&lt;/code&gt; for a home directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Postgres from source
&lt;/h2&gt;

&lt;p&gt;I checked all the steps right up to populating Postgres database tables. While its certainly possible to use R to analyze the data, my goal was to have a reason to install Postgres. Somewhat annoyingly for the purposes of this post, &lt;a href="https://www.postgresql.org/docs/current/install-short.html"&gt;the short version&lt;/a&gt;worked almost perfectly using &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10#simplified-installation-for-windows-insiders"&gt;WSL 2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only problem I had was that I don't know the password for the Administrator account so I couldn't use &lt;code&gt;su&lt;/code&gt;. Thankfully, I found that I could &lt;a href="https://stackoverflow.com/questions/37609356/windows-10-bash-ubuntu-su-root-password/37609466#37609466"&gt;use &lt;code&gt;sudo su&lt;/code&gt;instead&lt;/a&gt;. That confused me until I read some &lt;a href="https://askubuntu.com/questions/376199/sudo-su-vs-sudo-i-vs-sudo-bin-bash-when-does-it-matter-which-is-used"&gt;answers on Ask Ubuntu&lt;/a&gt;. Turns out &lt;code&gt;su&lt;/code&gt; asks for the password of the account you want to switch to and &lt;code&gt;sudo&lt;/code&gt; asks for the password of the current account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing prerequisites from the command line
&lt;/h3&gt;

&lt;p&gt;Since I wanted to install Postgres the &lt;em&gt;hard way&lt;/em&gt; I decided to try installing it on Windows using the Microsoft toolchain. Since I'm not a big fan of GUI installers, I was pleased to find I could use&lt;a href="https://docs.chocolatey.org/en-us/choco/setup"&gt;Chocolatey&lt;/a&gt; to install the prerequisites.&lt;sup&gt;4&lt;/sup&gt; After installing Chocolatey, open a PowerShell window (as an administrator) and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;choco install ActivePerl git openssl winflexbison python archiver -y 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That should install all of the third-party tools you'll need to build Postgres. You might need to add &lt;code&gt;C:\Perl64\bin&lt;/code&gt; to your &lt;code&gt;PATH&lt;/code&gt; and run&lt;code&gt;refreshenv&lt;/code&gt;. Then install the Visual Studio tools you'll need to build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;choco install visualstudio2019community windows-sdk-10.1 -y

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The &lt;code&gt;-y&lt;/code&gt; is optional and simply avoids prompting for confirmation by automatically saying "yes" to any questions the installer might ask. You normally want to just say yes.)&lt;/p&gt;

&lt;p&gt;While you are at it, you can install all sorts of useful software from the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;choco install Emacs vim texlive

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And even some of the software I installed by downloading a GUI installer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;choco install R.Studio wsl2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installing MSVC Build Tools
&lt;/h3&gt;

&lt;p&gt;There is one feature that I haven't figured out how to install via Chocolatey. It's the Visual Studio C++ build tools, which can be installed via the Visual Studio Installer. You can start it up from the Visual Studio 2019 menu system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tools =&amp;gt; Get Tools and Features...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also just run it independently. Either way, you'll want to modify your version of Visual Studio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modify =&amp;gt; Desktop development with C++ =&amp;gt; MSVC v142 - VS 2019 C++ x64/x86 build tools

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, I'm including the version numbers I used, but it probably will work fine with newer (and perhaps older) versions. Another constant problem with installing software is that sometimes new releases break stuff that used to work. For instance, &lt;a href="https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/"&gt;Ruby 3 came out recently&lt;/a&gt;and it &lt;a href="https://github.com/jekyll/jekyll/issues/8523"&gt;breaks the way I build my site&lt;/a&gt;. This is a constant problem with guides about software and closely related to the prerequisites problem. Most of the time "install X" is helpful, but sometimes you need to say "install version Y of X" instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Postgres
&lt;/h3&gt;

&lt;p&gt;At this point we're finally ready to start building Postgres! I'm going to show how to do that in PowerShell. But not just any PowerShell. For this you need to start up &lt;em&gt;Developer PowerShell for VS 2019&lt;/em&gt;. Regular PowerShell doesn't work because the build tools aren't readily available.&lt;sup&gt;5&lt;/sup&gt; There's also a Developer Command Prompt, but I prefer PowerShell for a few Unix-like enhancements. The following commands, create a &lt;code&gt;pg&lt;/code&gt; directory for playing in, move into that directory, get the Postgres source code, extract the files and move to directory where we'll build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir pg
cd pg
wget https://ftp.postgresql.org/pub/source/v13.2/postgresql-13.2.tar.bz2 -OutFile postgresql-13.2.tar.bz2
arc unarchive .\postgresql-13.2.tar.bz2
cd .\postgresql-13.2\src\tools\msvc\

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now PowerShell is really handy, but notice how the &lt;code&gt;wget&lt;/code&gt; command requires an &lt;code&gt;-OutFile&lt;/code&gt; parameter. If you leave it off, the command reads the URL, shows some metadata and &lt;a href="https://unix.stackexchange.com/questions/359972/wget-not-saving-file-after-download"&gt;&lt;em&gt;doesn't save the file&lt;/em&gt;&lt;/a&gt;. It's just an alias for &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.1#syntax"&gt;&lt;code&gt;Invoke-WebRequest -Uri&lt;/code&gt;&lt;/a&gt;. It's like they get it, but they don't get it. I'm not sure what's the point of fetching files from the internet and immediately throwing them away.&lt;/p&gt;

&lt;p&gt;Anyway, if you've set everything up right, you should be able to run the &lt;code&gt;.\build&lt;/code&gt; command. If you haven't installed all the right prerequisites or aren't running in the Developer PowerShell, you'll get an error like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS C:\pg\tmp\postgresql-13.2\src\tools\msvc&amp;gt; .\build
Unable to determine Visual Studio version: The nmake command wasn't found. at C:/pg/tmp/postgresql-13.2/src/tools/msvc/Mkvcbuild.pm line 93.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise, the output will end something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FinalizeBuildStatus:
  Deleting file ".\Release\euc2004_sjis2004\euc2004_sjis2004.tlog\unsuccessfulbuild".
  Touching ".\Release\euc2004_sjis2004\euc2004_sjis2004.tlog\euc2004_sjis2004.lastbuildstate".
Done Building Project "C:\pg\postgresql-13.2\euc2004_sjis2004.vcxproj" (default targets).

Done Building Project "C:\pg\postgresql-13.2\pgsql.sln" (default targets).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:04:01.81

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installing Postgres
&lt;/h3&gt;

&lt;p&gt;Once the build succeeds, it's time to install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.\install \pg

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, it doesn't much matter where you install Postgres. It can help to put it somewhere you will remember later. The &lt;a href="https://www.enterprisedb.com/downloads/postgres-postgresql-downloads"&gt;EDB installer&lt;/a&gt;puts it in &lt;code&gt;C:\Program Files\PostgreSQL\13&lt;/code&gt;, which probably is a better choice. Wherever you install it, you'll find a &lt;code&gt;bin&lt;/code&gt; directory that has all the commands you'll need to start the database. You'll need to create a &lt;code&gt;data&lt;/code&gt; directory to hold, well, all your data. While you could run using your own account, it's &lt;a href="https://www.postgresql.org/docs/current/postgres-user.html"&gt;better to run it under another user account&lt;/a&gt;. (A good choice is"postgres".) Either way, make sure your data directories (but not the executables) are owned by the account that will run Postgres.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;bin&lt;/code&gt; directory, you can find the commands to initialize a database directory, start a Postgres server using that data storage and create a database called "retrosheet":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.\initdb.exe -D \pg\data
.\pg_ctl -D \pg\data -l logfile start
.\createdb.exe retrosheet

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go ahead and make sure the database exists and is empty:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS C:\pg\bin&amp;gt; .\psql retrosheet
psql (13.2)
WARNING: Console code page (437) differs from Windows code page (1252)
         8-bit characters might not work correctly. See psql reference
         page "Notes for Windows users" for details.
Type "help" for help.

retrosheet=# \d
Did not find any relations.
retrosheet=#

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Writing Retrosheet data to Postgres
&lt;/h2&gt;

&lt;p&gt;Poor retrosheet database. Let's give it family, shall we?&lt;/p&gt;

&lt;p&gt;Now I have to admit something kinda embarrassing here. Building Postgres from source was surprisingly easy, but I made connecting to the database from R incredibly hard. My only excuse is that the last time I had to set up a database connection on my own was over a decade ago. Pretty much the only thing I remembered was that ODBC was involved somehow. When I mentioned how frustrating ODBC &lt;em&gt;still is to install&lt;/em&gt;, a colleague kindly pointed out it's not necessary anymore.&lt;/p&gt;

&lt;p&gt;What makes this especially embarrassing is that back in 2006, I wrote&lt;a href="https://github.com/jericson/exec_sql.pl/blob/master/exec_sql.pl"&gt;a Perl script to connect to arbitrary database servers&lt;/a&gt;using the &lt;a href="https://metacpan.org/pod/DBI"&gt;DBI module&lt;/a&gt; which is exeedingly similar to the &lt;a href="https://dbi.r-dbi.org/"&gt;R DBI package&lt;/a&gt;. Not only do you not need ODBC, DBI is a competitor.&lt;sup&gt;6&lt;/sup&gt; Connecting to our new database via R is as simple as installing two packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install.packages('DBI')
install.packages('RPostgres')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And using the appropriate connection string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require(DBI)

retrosheet_db &amp;lt;- dbConnect(RPostgres::Postgres(), 
                           dbname = 'retrosheet', 
                           host='localhost', 
                           port='5432', 
                           user='postgres')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, you don't need to specify the &lt;a href="https://chartio.com/resources/tutorials/how-to-set-the-default-user-password-in-postgresql/"&gt;postgres password&lt;/a&gt;when connecting via the same machine. If you do need a password, it's good practice to save it in an environment variable and use something like &lt;code&gt;password=Sys.getenv('PG_PWD')&lt;/code&gt; so you don't hardcode the secret. And with that, you can execute the &lt;code&gt;dbWriteTable&lt;/code&gt; and&lt;code&gt;dbGetQuery&lt;/code&gt; commands list in &lt;a href="https://billpetti.github.io/2019-08-10-build-retrosheet-event-roster-database-rstats-baseballr/"&gt;Bill Petti's instructions&lt;/a&gt;. It takes a while, but when everything is done, you can see two new tables have been created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=retrosheet=# \d
             List of relations
 Schema | Name | Type | Owner
-------------+---------------+-------+----------
 public | retro_pbp | table | postgres
 public | retro_rosters | table | postgres

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you are really lucky, they will have data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;retrosheet=# select count(*) from retro_pbp;
  count
---------------
 13792467
(1 row)

retrosheet=# select count(*) from retro_rosters;
 count
------------
 92727
(1 row)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Has anyone ever hit two grand slams in a single inning?
&lt;/h2&gt;

&lt;p&gt;Now we can start doing some baseball research. For instance, if you know that a grand slam is the only way to get 4 RBIs in a single play,&lt;sup&gt;7&lt;/sup&gt;it's not hard to find all the batters who have hit at least two grand slams in a game:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select game_id, bat_id, count(*) 
from retro_pbp p
where rbi_ct = 4
group by game_id, bat_id
having count(*) &amp;gt; 1;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;game_id&lt;/th&gt;
&lt;th&gt;bat_id&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;BOS199905100&lt;/td&gt;
&lt;td&gt;garcn001&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLE196806240&lt;/td&gt;
&lt;td&gt;nortj101&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLE199808140&lt;/td&gt;
&lt;td&gt;hoilc001&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LAN199904230&lt;/td&gt;
&lt;td&gt;tatif001&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIL200907270&lt;/td&gt;
&lt;td&gt;willj004&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIN196105090&lt;/td&gt;
&lt;td&gt;gentj101&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHA193605240&lt;/td&gt;
&lt;td&gt;lazzt101&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHA193907042&lt;/td&gt;
&lt;td&gt;taboj101&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SFN196607030&lt;/td&gt;
&lt;td&gt;clont101&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLA194607270&lt;/td&gt;
&lt;td&gt;yorkr101&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEX199509040&lt;/td&gt;
&lt;td&gt;ventr001&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEX200307290&lt;/td&gt;
&lt;td&gt;muelb001&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WS2197006260&lt;/td&gt;
&lt;td&gt;robif103&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(13 rows)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;While you might not understand the significance of this report, I did. It meant I had not only managed to install Postgres, but also load it up with over a 100 years of baseball history. One particular&lt;code&gt;bat_id&lt;/code&gt; stands out as the player I'm looking for. Next, I queried for all the times when a batter has hit two grand slams in a single inning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select game_id, inn_ct, bat_id, count(*) 
from retro_pbp 
where rbi_ct = 4 
group by game_id, inn_ct, bat_id 
having count(*) &amp;gt; 1;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;game_id&lt;/th&gt;
&lt;th&gt;inn_ct&lt;/th&gt;
&lt;th&gt;bat_id&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LAN199904230&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;tatif001&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(1 row)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now you can take that &lt;code&gt;game_id&lt;/code&gt;, plug it into the nearest search engine and discover &lt;a href="https://www.baseball-almanac.com/box-scores/boxscore.php?boxid=199904230LAN"&gt;St. Louis vs the Dodgers on April 23, 1999&lt;/a&gt;. There, in the third inning, Fernando Tatis slams twice. If you feel like it, you can watch &lt;a href="https://www.backtobaseball.com/playballregularseason.php?page=19&amp;amp;IDindex=LAN199904230&amp;amp;date=April+23%2C+1999"&gt;a crude animation&lt;/a&gt;of how it happened. Think about the series of events that had to happen just so in order for Tatis to get up with the bases loaded twice.&lt;/p&gt;

&lt;p&gt;Meanwhile, think of all the little things that needed to be initiated to get a working database server up and running. Thankfully software can be quite a bit easier to manipulate than a baseball game.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;If you've watched as much baseball as I have, you know the
answer. Don't spoil it for everyone else! ↩&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn2"&gt;
&lt;p&gt;The #1 revelation was that Windows uses the Control key for most
of the stuff Mac uses the Command key for. To make life more
complicated, Mac keyboards have an Option key that functions like
Alt &lt;em&gt;and&lt;/em&gt; it's in the same position where the Windows key is on a
PC keyboard. Eventually I realized I just want to be able to use
my thumb rather than my pinkie to copy and paste things. So making
Alt into another Control key and making the Windows key the new
Alt solved my problem. ↩&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn3"&gt;
&lt;p&gt;That said, it's a little much in R Studio when it also puts the
output of the scripts in the window where the source
is. Fortunately you can turn that off by going to Tools =&amp;gt; Global
Options =&amp;gt; R Markdown =&amp;gt; Basic =&amp;gt; Show output line for all R
Markdown documents. ↩&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn4"&gt;
&lt;p&gt;A big hat-tip to
&lt;a href="https://twitter.com/JourneymanGeek"&gt;@JourneymanGeek&lt;/a&gt; who &lt;a href="https://twitter.com/JourneymanGeek"&gt;pointed
this out to me&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn5"&gt;
&lt;p&gt;There is certainly some way of setting up environment variables
to make this work, but this post is way too long already and I
can't be bothered to figure it out. Just use the Developer
PowerShell. ↩&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn6"&gt;
&lt;p&gt;Interestingly, DBI can connect with a database connected to
ODBC. This fact made my searches misleading since it's entirely
&lt;em&gt;possible&lt;/em&gt; (but rarely &lt;em&gt;desirable&lt;/em&gt;) to connect to Postgres that
way. ↩&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn7"&gt;
&lt;p&gt;I later doublechecked I got the same result if I included only
place that &lt;a href="http://chadwick.sourceforge.net/doc/cwevent.html"&gt;cwevent coded as a home
run&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>I'm joining EDB as a Developer Advocate</title>
      <dc:creator>Jon Ericson</dc:creator>
      <pubDate>Fri, 30 Apr 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/jericson/im-joining-edb-as-a-developer-advocate-3329</link>
      <guid>https://dev.to/jericson/im-joining-edb-as-a-developer-advocate-3329</guid>
      <description>&lt;p&gt;My &lt;a href="///2021/04/23/job_hunting.html"&gt;job hunt&lt;/a&gt; is over and, as promised, I'm writing about my latest job ever. I'm going to be a &lt;a href="https://www.builtinboston.com/job/engineer/developer-advocate/47595"&gt;Developer Advocate at EDB&lt;/a&gt;. Not coincidentally at all, my friend &lt;a href="https://twitter.com/shog9/status/1233591329491283968"&gt;Shog9 is &lt;em&gt;also&lt;/em&gt; Developer Advocate at EDB&lt;/a&gt;. Guess I've been starving for stories about apple farming. Or maybe I don't want to break &lt;a href="///2020/07/08/reader_mail.html"&gt;my streak of getting jobs because people already know me&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I... can't really believe this is happening. It's pretty normal for me to assume there will be some mistake and actually I don't have a job. Not sure why because I'm normally optimistic. But I have a UPS tracking number that suggests my laptop is on it's way and I signed a bunch of documents before my (presumed) start date on Monday. I finally feel comfortable writing about what I'm going to be doing. (And in six months I'll read this and &lt;em&gt;laugh and laugh&lt;/em&gt; at how naive I once was.)&lt;/p&gt;

&lt;h2&gt;
  
  
  My neighbor's tankless heater.
&lt;/h2&gt;

&lt;p&gt;The guy next door has been building a house for well over a year and a half. I used to see him come over to inspect the progress. A month or two ago he finally moved in. I was so glad not to hear construction sounds during the day. But he also installed two external tankless water heaters and every morning at 8:30 I hear this horrific whine. I'm familiar with the sound since I also have an external tankless heater and it used to make the same noise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rmype3VO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jlericson.com/images/tankless.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rmype3VO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jlericson.com/images/tankless.jpg" alt="My tankless water heater." width="740" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For clarity, this is &lt;em&gt;my&lt;/em&gt; tankless unit that I installed with the help of my father-in-law. We have plans to fix the jank.&lt;/p&gt;

&lt;p&gt;Anyway, the problem is likely the result of harmonic resonance in the flexible gas line. It's a common problem for natural gas appliances such as fireplaces, fire pits and tankless heaters. One solution is to use a flex line that has alternating ridge patterns which break up the flow enough to avoid an annoying whistle.&lt;/p&gt;

&lt;p&gt;I bring it up because consumers who replace their water heater tanks with tankless are likely to just reuse the gas line that was already in place. Since tankless heaters need much higher gas volume while hot water is running, they are far more susceptible to whistling flex lines. So the average person installing these systems is liable to blame the heater (which is new) and not the line (which worked just fine before).&lt;/p&gt;

&lt;p&gt;I'd suggest manufacturers of tankless heaters need "installer advocates" to surface this sort of problem to the rest of the company. First, someone has to know the problem exists even though it's not directly related to the product they sell. Second, someone needs to make sure installers are aware of the solution. Maybe the installation manual could call the problem out clearly. The model I have warned that "gas flex lines are not recommended", but doesn't say why. Clearer warnings about the whistle problem might have helped.&lt;/p&gt;

&lt;p&gt;Other solutions might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Include the right sort of flex line with the unit. (But that adds to the expense and many customers won't need it.)&lt;/li&gt;
&lt;li&gt;Promote a line of instructional videos in which experts explain the problem.&lt;/li&gt;
&lt;li&gt;Design the heater with a microphone that detects a whistle and adjusts the flow rate to eliminate it. (Again adding to the expense and maybe not practical.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The job listing
&lt;/h2&gt;

&lt;p&gt;Normally job listings run together for me, but &lt;a href="https://web.archive.org/web/20210424161641/https://www.builtinboston.com/job/engineer/developer-advocate/47595"&gt;the one for my new job&lt;/a&gt;is different. &amp;lt;!--(I've pasted a copy of the whole thing at the bottom of&lt;br&gt;
this post in case the link stops working in the future.)--&amp;gt; Some parts of the description spoke to me in particular.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As a Developer Advocate, you will join a team of user experience and software development professionals on a mission to make working with Postgres easier for developers, data scientists, data wranglers, operators, and the ever-expanding ecosystem of technologists who rely on Postgres to innovate at speed. You will report into the Chief Experience Officer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The job is making Postgres easier to use.&lt;/li&gt;
&lt;li&gt;I report directly to the &lt;a href="https://www.enterprisedb.com/brad-noble"&gt;Chief Experience Officer&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So this isn't a marketing job (directly) and there's not a lot of management layers. That's good news because it means we can tackle whatever might be the Postgres equivalents of whistling flex lines. One of the painful points of being a community manager around the time I left Stack Overflow was there were so many people in the hierarchy we regularly got mixed messages about what we were responsible for.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Make Postgres easier: identify points of friction in Postgres and EDB products, develop approaches to address them&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've used Oracle, MS SQL Server, mySQL and SQLite. Each of these has strengths and weaknesses. I've only recently gotten into Postgres and I like what I see:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dipping my toe into SQL again. This time with &lt;a href="https://twitter.com/PostgreSQL?ref_src=twsrc%5Etfw"&gt;@PostgreSQL&lt;/a&gt;. Gotta say I was delighted to discover I can write things like:  &lt;/p&gt;

&lt;p&gt;where age(last_posted_at) &amp;lt; '6 months'  &lt;/p&gt;

&lt;p&gt;and it works as expected!&lt;/p&gt;

&lt;p&gt;— Jon Ericson (@jlericson) &lt;a href="https://twitter.com/jlericson/status/1346886078100344836?ref_src=twsrc%5Etfw"&gt;January 6, 2021&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Identify and engage with new communities which stand to benefit from Postgres&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;A paradox of community management is you don't need to be an extrovert to do the work. I'm the sort of introvert who is happy to chat about some topic of interest, but once the conversation moves to mundane territory, I struggle to maintain interest. It is an act of love (rarely recognized) when I studiously listen to someone else's concerns. More to the point, it takes energy for me to stay engaged.&lt;/p&gt;

&lt;p&gt;But this sort of work, telling people about a technology that excites me, also energized me. Speaking of which:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Collaborate with product, engineering, and marketing teams&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Y'all won't believe I'm an introvert when I tell you I loved this part of the job at Stack Overflow and College Confidential. And yes, I even enjoyed meeting with marketing. Again, being able to talk about interesting topics made all the difference.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Talk to Postgres users and EDB customers and listen for not only their needs but also their ideas for the future of Postgres&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ultimately the secret to community management is leaning on incredible people who know (and care) more than you do about the product.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Willingness to analyze, understand, and extend existing cultural and technical systems&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I read this requirement, I knew this was the job for me. It really is my happy place.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We know it takes a unique mix of people and skills to help us in our mission to supercharge Postgres, and we understand that not everyone will check every box. We'd love to hear from you and we want you to apply!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More job listings should include something like this. I'm confident I do check most of the boxes, but some of the best candidates for this sort of work &lt;a href="///2021/03/23/2021_CMX_report.html"&gt;know how hard it can be&lt;/a&gt;. They need a bit of encouragement to stretch their skills a bit.&lt;/p&gt;

&lt;p&gt;And that's what I hope I'll be able to do starting next week.&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>The joy of self answering</title>
      <dc:creator>Jon Ericson</dc:creator>
      <pubDate>Sat, 31 Aug 2019 04:52:07 +0000</pubDate>
      <link>https://dev.to/jericson/the-joy-of-self-answering-4po2</link>
      <guid>https://dev.to/jericson/the-joy-of-self-answering-4po2</guid>
      <description>&lt;p&gt;When Stack Overflow started, there wasn't a lot of content for me. Most people seemed interested in asking about obscure Microsoft products such as &lt;a href="https://insights.stackoverflow.com/trends?tags=c%23%2C.net%2Casp.net%2Csql-server"&gt;C# and .NET&lt;/a&gt;. I worked at a UNIX shop and we used reliable technology like &lt;a href="https://insights.stackoverflow.com/trends?tags=c%2Cshell%2Cperl%2Coracle"&gt;C and Perl&lt;/a&gt;. But I was intrigued by the idea of a site dedicated to questions and answers, so I thought I'd try my hand at asking questions.&lt;/p&gt;

&lt;p&gt;By the way, Stack Overflow interested me because I had read &lt;a href="http://shop.oreilly.com/product/9781565925373.do"&gt;&lt;em&gt;Practical Internet Groupware&lt;/em&gt;&lt;/a&gt; by Jon Udell sometime in the early 2000s. (Or perhaps read &lt;em&gt;about&lt;/em&gt; the book enough to be excited about the concept.) The premise of the book was that the internet would radically change the way people interact with each other since it allows groups to collaborate at scale. It's impossible to explain how exciting this idea was since we now accept it as obviously true. But before Twitter, Facebook, podcasts, blogs or even forums, few people guessed that the internet would democratize access to public discourse.&lt;/p&gt;

&lt;p&gt;Stack Overflow tackles one, very specific, problem: uneven access to arcane programming knowledge. It's hard for me to recall, but there was a time when every programmer had to discover on their own oddities such as:&lt;/p&gt;


&lt;div class="ltag__stackexchange--container"&gt;
  &lt;div class="ltag__stackexchange--title-container"&gt;
    
      &lt;div class="ltag__stackexchange--title"&gt;
        &lt;h1&gt;
          &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Gn-iPj_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackoverflow-logo-b42691ae545e4810b105ee957979a853a696085e67e43ee14c5699cf3e890fb4.svg" alt=""&gt;
            &lt;a href="https://stackoverflow.com/questions/583889/how-can-you-untar-more-than-one-file-at-a-time" rel="noopener noreferrer"&gt;
              
            &lt;/a&gt;
        &lt;/h1&gt;
        &lt;div class="ltag__stackexchange--post-metadata"&gt;
          &lt;span&gt;Feb 24 '09&lt;/span&gt;
            &lt;span&gt;Comments: &lt;/span&gt;
            &lt;span&gt;Answers: 3&lt;/span&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;a class="ltag__stackexchange--score-container" href="https://stackoverflow.com/questions/583889/how-can-you-untar-more-than-one-file-at-a-time" rel="noopener noreferrer"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y9mJpuJP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackexchange-arrow-up-eff2e2849e67d156181d258e38802c0b57fa011f74164a7f97675ca3b6ab756b.svg" alt=""&gt;
        &lt;div class="ltag__stackexchange--score-number"&gt;
          76
        &lt;/div&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wif5Zq3z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackexchange-arrow-down-4349fac0dd932d284fab7e4dd9846f19a3710558efde0d2dfd05897f3eeb9aba.svg" alt=""&gt;
      &lt;/a&gt;
    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--body"&gt;
    
&lt;p&gt;I have a bunch of &lt;code&gt;tar&lt;/code&gt; files in a directory and I want to extract all the files from them at once.  But this doesn't seem to do anything:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tar xf *.tar
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What's going on here?  How do I untar a bunch of files at once?&lt;/p&gt;

    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--btn--container"&gt;
    
      &lt;a href="https://stackoverflow.com/questions/583889/how-can-you-untar-more-than-one-file-at-a-time" rel="noopener noreferrer"&gt;Open Full Question&lt;/a&gt;
    
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Then you'd need to walk around the office to see if anyone was proficient enough in shell commands to find a working solution. Or, just struggle through untarring hundreds of files by hand. (Ask me how I know this.) But with Stack Overflow, someone can come along, see the question and provide an answer:&lt;/p&gt;


&lt;div class="ltag__stackexchange--container"&gt;
  &lt;div class="ltag__stackexchange--title-container"&gt;
    
      &lt;div class="ltag__stackexchange--title"&gt;
        &lt;h1&gt;
          &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Gn-iPj_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackoverflow-logo-b42691ae545e4810b105ee957979a853a696085e67e43ee14c5699cf3e890fb4.svg" alt=""&gt;
            &lt;a href="https://stackoverflow.com/questions/583889/how-can-you-untar-more-than-one-file-at-a-time/583891#583891" rel="noopener noreferrer"&gt;
              &lt;span class="title-flare"&gt;answer&lt;/span&gt; re: How can you untar more than one file at a time?
            &lt;/a&gt;
        &lt;/h1&gt;
        &lt;div class="ltag__stackexchange--post-metadata"&gt;
          &lt;span&gt;Feb 24 '09&lt;/span&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;a class="ltag__stackexchange--score-container" href="https://stackoverflow.com/questions/583889/how-can-you-untar-more-than-one-file-at-a-time/583891#583891" rel="noopener noreferrer"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y9mJpuJP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackexchange-arrow-up-eff2e2849e67d156181d258e38802c0b57fa011f74164a7f97675ca3b6ab756b.svg" alt=""&gt;
        &lt;div class="ltag__stackexchange--score-number"&gt;
          147
        &lt;/div&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wif5Zq3z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/stackexchange-arrow-down-4349fac0dd932d284fab7e4dd9846f19a3710558efde0d2dfd05897f3eeb9aba.svg" alt=""&gt;
      &lt;/a&gt;
    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--body"&gt;
    
&lt;h1&gt;What's going on here?&lt;/h1&gt;
&lt;p&gt;Originally, the &lt;code&gt;tar&lt;/code&gt; command was intended for use with magnetic tape devices.  Since it only made sense to execute &lt;code&gt;tar&lt;/code&gt; on one device at a time, the syntax was designed to assume one and only one device.  The first file or directory passed was assumed to…&lt;/p&gt;
    
  &lt;/div&gt;
  &lt;div class="ltag__stackexchange--btn--container"&gt;
    
      &lt;a href="https://stackoverflow.com/questions/583889/how-can-you-untar-more-than-one-file-at-a-time/583891#583891" rel="noopener noreferrer"&gt;Open Full Answer&lt;/a&gt;
    
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;And then roughly 68 thousand people could find that very same answer and learn something about how the UNIX shell works.&lt;/p&gt;

&lt;p&gt;The twist: it doesn't have to be different people who ask and answer. I figured out my own solution and instead of moving on with my life, I posted the answer to my own question. Maybe not the most monumental thing in the world, but rather my small way to help people out in the future.&lt;/p&gt;

&lt;p&gt;Now it can be hard to ask a question as if you didn't know the answer and there are people on the site who are suspicious of self-answered questions. But if you wish there was a bit of programming knowledge available on the internet, you don't need to wait for someone else to ask the question. &lt;/p&gt;

</description>
      <category>stackoverflow</category>
    </item>
  </channel>
</rss>
