<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>History · XB Field Notes</title><link>https://www.xbcatm.com/tags/history/</link><description>Illustrated field notes on HTTP, DNS, TLS, Caddy, SSH, releases, and recovery.</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://www.xbcatm.com/tags/history/index.xml" rel="self" type="application/rss+xml"/><item><title>Bash history is your searchable command log</title><link>https://www.xbcatm.com/posts/linux-bash-history-session/</link><pubDate>Mon, 28 Feb 2028 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/posts/linux-bash-history-session/</guid><description>Bash history supports command recall, but session memory, disk persistence, filters, and explicit imports determine what remains searchable.</description><content:encoded>&lt;p&gt;A useful command history saves retyping, but it is not a complete record of everything executed. Bash normally enables history in interactive shells, and settings can exclude entries or limit retention. The searchable list in a running shell and the history file on disk are separate states. That distinction explains why a command may be visible in one terminal, absent in another, and lost when an unwritten session ends unexpectedly.&lt;/p&gt;
&lt;h2 id="session-memory-differs-from-the-file"&gt;Session memory differs from the file&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;HISTSIZE&lt;/code&gt; limits the in-memory history entries; &lt;code&gt;HISTFILESIZE&lt;/code&gt; limits the saved file&amp;rsquo;s lines. Multiline commands and timestamp records mean that line counts and command counts are not interchangeable. &lt;code&gt;HISTFILE&lt;/code&gt; selects the file, normally the user&amp;rsquo;s Bash history file. An unset or empty value prevents ordinary saving, and an unwritable location can leave apparently healthy in-memory recall with no persistent record.&lt;/p&gt;
&lt;p&gt;Bash records command text before parameter expansion but after history expansion, subject to &lt;code&gt;HISTCONTROL&lt;/code&gt; and &lt;code&gt;HISTIGNORE&lt;/code&gt;. A saved line containing a variable therefore does not necessarily reveal the value used during the original execution. Current directories, aliases, functions, environment values, and external files can all change before a command is recalled. History preserves useful input, not a reproducible execution environment or a trustworthy audit trail.&lt;/p&gt;
&lt;h2 id="appending-does-not-refresh-other-terminals"&gt;Appending does not refresh other terminals&lt;/h2&gt;
&lt;p&gt;On normal exit, Bash saves history; &lt;code&gt;histappend&lt;/code&gt; selects appending rather than overwriting the file. Without earlier writes, abnormal termination can lose all unsaved entries, not merely the final command. &lt;code&gt;history -a&lt;/code&gt; appends newly entered lines that this session has not already appended. Saving before exit reduces that loss window, but does not promise durable storage through every system failure.&lt;/p&gt;
&lt;p&gt;Another running shell has its own list. It needs an import such as &lt;code&gt;history -n&lt;/code&gt; to read newly appended lines; enabling &lt;code&gt;histappend&lt;/code&gt; alone does not make another terminal&amp;rsquo;s searches update live. &lt;code&gt;history -r&lt;/code&gt; reads the entire file into the existing list and can introduce duplicates. &lt;code&gt;history -w&lt;/code&gt; replaces the file with the current list and can discard other sessions&amp;rsquo; records. These operations should not be treated as interchangeable synchronization commands.&lt;/p&gt;
&lt;p&gt;If append and import operations are integrated into &lt;code&gt;PROMPT_COMMAND&lt;/code&gt;, preserve existing prompt hooks and any use of the preceding command&amp;rsquo;s status. Replacing a configured hook wholesale can break other shell behavior. Concurrent sessions also do not create a reliable global execution order merely by sharing a file. Keep separate operational logs when ordering, exit status, or accountability matters.&lt;/p&gt;
&lt;h2 id="search-inspect-then-execute"&gt;Search, inspect, then execute&lt;/h2&gt;
&lt;p&gt;In the usual Emacs-style Readline bindings, Ctrl-R searches backward incrementally, and pressing it again finds older matches. Use an editing key to leave the search and inspect the selected line before running it; Ctrl-G cancels the search. Enter accepts the command. Ctrl-J is also a newline and must not be described as a harmless preview key. Bindings can differ in another editing mode or a customized terminal.&lt;/p&gt;
&lt;p&gt;Inspect the hostname, directory, options, and intended target whenever reusing an old command. A command that was correct last month may address a different environment today. Prefer a distinctive search fragment and review the whole line, rather than trusting that the first matching command is the right operation.&lt;/p&gt;
&lt;h2 id="when-it-breaks"&gt;When it breaks&lt;/h2&gt;
&lt;p&gt;Missing commands can result from filtering, retention limits, a different history file, failed saving, or an unrefreshed session. Check those causes separately. &lt;code&gt;ignoredups&lt;/code&gt; excludes consecutive duplicates, not every duplicate in the entire list. &lt;code&gt;ignoreboth&lt;/code&gt; combines that behavior with &lt;code&gt;ignorespace&lt;/code&gt;; it does not produce a globally unique command archive.&lt;/p&gt;
&lt;p&gt;A leading space excludes an entry only when the relevant setting is active. It does not remove terminal recordings, process arguments, or logs written elsewhere, so do not put credentials directly into command lines and rely on history filtering for secrecy. Diagnostic examples should use synthetic entries and a temporary history file, rather than printing someone&amp;rsquo;s real recent commands.&lt;/p&gt;
&lt;h2 id="check-it-quickly"&gt;Check it quickly&lt;/h2&gt;
&lt;p&gt;Run this with Python 3, Bash, and standard Unix utilities. The environment points Bash to a temporary file before it starts. Only synthetic entries are inspected. The brace group avoids recording the demonstration&amp;rsquo;s own control commands after history is enabled.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;subprocess&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;tempfile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;set -eu
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;set -o history
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history -c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history -s &amp;#39;demo original&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history -w &amp;#34;$HISTFILE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;printf &amp;#39;first-file:\n&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;cat &amp;#34;$HISTFILE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history -c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history -s &amp;#39;demo replacement&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history -w &amp;#34;$HISTFILE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;printf &amp;#39;replacement-file:\n&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;cat &amp;#34;$HISTFILE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history -r &amp;#34;$HISTFILE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;printf &amp;#39;memory-after-reread:\n&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;history | sed &amp;#39;s/^[[:space:]]*[0-9][0-9]*[[:space:]]*//&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;unset HISTFILE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;}&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;tempfile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TemporaryDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bash-history-demo-&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;history_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;history&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BASH_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HISTFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history_path&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;HISTSIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;100&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HISTFILESIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;100&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HISTCONTROL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HISTIGNORE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HISTTIMEFORMAT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bash&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--noprofile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--norc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first file contains &lt;code&gt;demo original&lt;/code&gt;; after replacement it contains only &lt;code&gt;demo replacement&lt;/code&gt;. Reading that file into a list already containing the replacement produces two identical entries in memory. This verifies overwrite and import semantics without executing the stored strings. It does not claim to test keyboard bindings or crash durability, which require their own observations.&lt;/p&gt;
&lt;h2 id="sources"&gt;Sources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tiswww.case.edu/php/chet/bash/bashref.html#Bash-History-Facilities"&gt;Bash history facilities&lt;/a&gt;, session lists and saving to the history file, checked 2026-09-07.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tiswww.case.edu/php/chet/bash/bashref.html#Bash-History-Builtins"&gt;Bash history builtins&lt;/a&gt;, append and replacement versus importing entries, checked 2026-09-07.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tiswww.case.edu/php/chet/bash/bashref.html#Commands-For-History"&gt;Readline history commands&lt;/a&gt;, search and command-acceptance bindings, checked 2026-09-07.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>