How to save terminal output to a file for future reference
January 8th, 2019
Recently I upgraded to Mojave on my Macbook Pro (late 2015). I then
decided it was also time to upgrade Homebrew. I needed to update
so thought I would update everything else.
postgres was a success. Read more
in my posts entitled
Upgrading PostgreSQL from version 10.4 to 11.1 via Homebrew (OSX)
Changing your (Homebrew) PostgreSQL configuration from trust to md5.
Unbeknownst to me until today, my Ruby system install broke in the process. I hadn’t done anything related to Ruby installations in a couple of years, and had to refresh my memory on it. Had I installed with RVM? I checked to see if I had it installed on my computer. No. What else could I have used to manage my Ruby installs? I googled for information regarding the error I got when trying to watch a file on a Node project I am working on in which I decided to switch from CSS to SCSS (today). I just find it to be a much more efficient and powerful way to work with global styles.
HOWEVER, when I wanted to go back and write about this experience after I had
already closed my Terminal instance, I couldn’t retrieve the
stderr(s) of my commands! So I decided to look into a way of making sure
that it would not happen again. My search was successful. I found a command(s)
that would print out either the output of a command or the
Terminal to a text file of my choosing. I made sure to test it before
writing this post, and it worked!
I took a simple command,
ruby -v, which outputs the (system) version of ruby
that is running on my machine and printed it to a file on my desktop called
ruby-output.txt. The following is the command I ran in Terminal:
ruby -v 2>&1 | tee ~/desktop/ruby_output.txt
This resulted in both
output to the
output to a new
file on my desktop called
ruby_output.txt. If I had already known about
this command, I could have re-run the
ruby -v command along with the rest of
this new command in Terminal after receiving the Ruby related errors so
as to reference that information when writing my post! This time around I went
back to my Google searches to see what I had googled. But in future, I
will have a much more reliable and (time) efficient solution!
Important note: If you want to add another command output to the same file that doesn’t overwrite the previous output, do NOT use this exact command. It will overwrite the previous output. What happens is, a new file of the same name overwrites the existing file and also replaces the previous output with the current output! In order to append new output without overwriting the previous output, use the following command:
sass --watch public/styles/styles.scss >> ~/desktop/ruby_output.txt
However, nothing gets output to Terminal. Only to the file! If you want to see the output in Terminal as well as outputting to the file, run the following command:
ruby -v 2>>&1 | tee -a ~/desktop/ruby_output.tx
Let’s break this down.
ruby -v is the command I wanted to run in Terminal
to get back the system version I am using on my computer. The following is
output in Terminal:
ruby 2.7.0dev (2019-01-17) [x86_64-darwin18]
2 stands for
standard error (
1 stands for
standard output (
|, in this case, is
used to pass the
stdout or the
stderr to the
tee -a ~/desktop/ruby_output.txt command.
>> means to append. I am telling
Terminal to append the
stdout. If I only used
there would be an overwrite, as shown previously.
tee allows you to
stdout to a file while piping the same
another command. Here, the other command is
always used with a
|) preceding it.
AND it was also output to the
ruby_output.txt file living on my desktop. In
addition, nothing was overwritten. The
stdout was simply appended
to the rest of the stdout I had added previously. The key to this is in the
flag, which is short for append. For example, this is what is
currently residing in that file:
ruby 2.7.0dev (2019-01-17) [x86_64-darwin18] >>> Sass is watching for changes. Press Ctrl-C to stop. ruby 2.7.0dev (2019-01-17) [x86_64-darwin18]
If I really wanted to get fancy, I could have done the following:
script -a ~/desktop/log-all.txt
I would start this script at the beginning of a Terminal session.
script means that I am starting a script native to Unix which
will print out both Terminal
stdout to a file on my
log-all.txt. The default command for this on Linux is
script session.log. However, I have seen the log file can be called anything
that will NOT overwrite some important system file of the same name in the same
location!!! So be careful when creating a script with
script. The above
output the following in Terminal:
Script started, output file is /Users/mariacam/desktop/log-all.txt
Then, when I wanted to stop the script, I typed the following in Terminal:
You can also end a session with
Control + D. Then all
from Terminal is printed out to the destination file.
But let’s say I just wanted to print out a history of my commands to a file. This is actually what I did just now:
history >> ~/desktop/history_log.txt
And I get the my Command Line
history printed out in
my desktop. I am not sharing it here as some sensitive information is logged
there! Anything you type out in Command Line, including
passwords and such, will appear in your history. So be careful
about what kind of Command Line information you share.
Some of the commands listed there I hadn’t even used in AGES! And it goes up to the latest one, not including those in the current session. I have to log out of it before it is included in that history.
This is all well and good. From too little information to too much! I like the
script session approach for my current purposes of committing information to
“printed history”. It gives me the information I need and from the time I need
to include both Terminal
stdout! Of course if I forget to run
script at the beginning of my session (and even later), and I just want to save
the anomalies I come across, I can just use the command:
ruby -v 2>>&1 | tee -a ~/desktop/ruby_output.txt
There is so much more on this topic. I highly encourage everyone to delve deeper
into Command Line. Believe me, it will help you to become a much better
developer in so many different ways. Not just through
npm i or
git init, but
will permit you to easily retrieve why something worked or didn’t work (and
write an accurate post about it even after logging out of your Terminal
instance). And so much more! Last but not least, it permits you to gain a
better understanding and control of your machine!