<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Blog — George Mishurovsky: posts tagged mac</title>
<link>https://mishurovsky.com/blog/?go=tags/mac/</link>
<description>A blog by George Mishurovsky — a senior software engineer with a medical degree. Drawing from both engineering and scientific thinking, he explores software, architecture, design, psychology, and product thinking.</description>
<author></author>
<language>en</language>
<generator>Aegea 11.3 (v4134e)</generator>

<itunes:owner>
<itunes:name></itunes:name>
<itunes:email>george@mishurovsky.com</itunes:email>
</itunes:owner>
<itunes:subtitle>A blog by George Mishurovsky — a senior software engineer with a medical degree. Drawing from both engineering and scientific thinking, he explores software, architecture, design, psychology, and product thinking.</itunes:subtitle>
<itunes:image href="https://mishurovsky.com/blog/pictures/userpic/userpic-square@2x.jpg?1753619610" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>How to View Past Terminal Commands — from Simple to Robust</title>
<guid isPermaLink="false">5</guid>
<link>https://mishurovsky.com/blog/?go=all/how-to-quickly-retrieve-past-terminal-commands/</link>
<pubDate>Sun, 03 Aug 2025 14:18:24 +0200</pubDate>
<author></author>
<comments>https://mishurovsky.com/blog/?go=all/how-to-quickly-retrieve-past-terminal-commands/</comments>
<description>
&lt;p&gt;Suppose you want to re-run some shell command you used ten days ago. It is a complex one; you do not remember exact flags and argument values, and it would take a long time to recall an exact text. What can you do?&lt;/p&gt;
&lt;h2&gt;1. The upwards arrow&lt;/h2&gt;
&lt;p&gt;Majority of devs working with command line knows it. Press “up” to see a previous command, press “down” for a next command, press “Ctrl+C” to drop whatever is in the prompt and start fresh.&lt;/p&gt;
&lt;p&gt;This approach works, but gets very tedious when you need to find a command you used last week or last month. Once more than ten or twenty commands have passed, scrolling through them becomes tedious.&lt;/p&gt;
&lt;h2&gt;2. Terminal history file&lt;/h2&gt;
&lt;p&gt;All the commands you enter into a terminal get stored in &lt;span class="inline-code"&gt;.bash_history&lt;/span&gt; file (or &lt;span class="inline-code"&gt;.zsh_history&lt;/span&gt; if you are on Mac) up to a certain limit. Thus, you can run:&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;cat ~/.bash_history # output all into the terminal
less ~/.bash_history # or use any text viewer
tail -n 20 ~/.bash_history # or observe only the most recent n lines
cat ~/.bash_history | grep whatever # to search for specific patterns&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This method gives you full access to your history file, and lets you search more flexibly.&lt;/p&gt;
&lt;h2&gt;3. &lt;span class="inline-code"&gt;history&lt;/span&gt; command&lt;/h2&gt;
&lt;p&gt;Almost the same as using the history file directly: you get a list commands, but now it is &lt;i&gt;numbered&lt;/i&gt;.&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;history -20 # show the last 20 commands
history -500 | grep ssh # search for a specific patter in a command
!780 # execute command with order number 780&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But there is one important difference from direct usage of &lt;span class="inline-code"&gt;.bash_history&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="inline-code"&gt;history&lt;/span&gt; command uses the last &lt;span class="inline-code"&gt;HISTSIZE&lt;/span&gt; history entries (default 1000)&lt;/li&gt;
&lt;li&gt;&lt;span class="inline-code"&gt;.bash_history&lt;/span&gt; file uses the last &lt;span class="inline-code"&gt;HISTFILESIZE&lt;/span&gt; entries (default 2000)&lt;br /&gt;
So, if your command was run a really long time ago, &lt;span class="inline-code"&gt;history&lt;/span&gt; may not find it, but direct inspection of &lt;span class="inline-code"&gt;.bash_history&lt;/span&gt; can do.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. &lt;span class="inline-code"&gt;fc -l&lt;/span&gt; command&lt;/h2&gt;
&lt;p&gt;This command behaves very similar to &lt;span class="inline-code"&gt;history&lt;/span&gt;, with an additional ability to display ranges of command numbers::&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;fc -l -20 # show the last 20 commands
fc -l 100 150 # show commands 100 to 150&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2&gt;5. Reverse-i-search&lt;/h2&gt;
&lt;p&gt;This is the most powerful approach. Press “Ctrl+R” to enter reverse incremental search mode. Initially you get no output; start writing any part of a command you remember, e. g. &lt;span class="inline-code"&gt;ssh&lt;/span&gt; or &lt;span class="inline-code"&gt;input.json&lt;/span&gt; or &lt;span class="inline-code"&gt;-n 10&lt;/span&gt; — and you will see the first full command entry with that match!&lt;/p&gt;
&lt;p&gt;From there, you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Press “Enter” to execute the command immediately&lt;/li&gt;
&lt;li&gt;Use left/right arrow keys to move within a command to edit it, then press “Enter” to execute&lt;/li&gt;
&lt;li&gt;Press “Ctrl+R” again to go to the next, older match&lt;/li&gt;
&lt;li&gt;Press “Ctrl+S” to go to the previous, newer match (see comment below)&lt;/li&gt;
&lt;li&gt;Press up-down arrows to view to nearby entries in history around the match&lt;/li&gt;
&lt;li&gt;Press “Ctrl+C” or “Ctrl+G” to exit the search&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On many systems “Ctrl+S” shortcut will not work, as it is prioritized to pause terminal output (press “Ctrl+Q” to resume). To make it work for reverse-i-search, add &lt;span class="inline-code"&gt;stty -ixon&lt;/span&gt; to your shell config. It will disable “Ctrl+S” / “Ctrl+Q” shortcuts for terminal flow control:&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;echo &amp;quot;stty -ixon&amp;quot; &amp;gt;&amp;gt; ~/.bashrc
source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Happy command line manipulation!&lt;/p&gt;
&lt;p&gt;💡 This post has a second part: &lt;a href="https://mishurovsky.com/blog/all/shell-configs-for-better-command-history-search/"&gt;Shell Configs for Better Command History Search&lt;/a&gt;&lt;/p&gt;
</description>
</item>


</channel>
</rss>