Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -Werror=implicit-function-declaration
-fstack-protector-strong -fstack-clash-protection -Wformat
-Werror=format-security -fcf-protection -Wall
uname output: Linux sappc1 6.12.17-amd64 #1 SMP PREEMPT_DYNAMIC Debian
6.12.17-1 (2025-03-01) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
[bashbug output manually adapted to real version ...]
Bash Version: 5.3
Commit: a6767763de5e7859107711b166a64a9e4a77a8ae
Release Status: compiled from recent devel branch
Description:
Bash skips empty lines when reading history file in multiline mode.
Repeat-By:
Start Bash as "bash --norc --noprofile". Then execute the
following commands:
------------------------- repro 1/2 -------------------------
shopt -s cmdhist lithist
HISTTIMEFORMAT='%F %T '
HISTFILE="/tmp/testhist"
cat << 'EOH' > $HISTFILE
#1
cat << 'EOF' | wc -l
abc
def
ghi
EOF
EOH
history -c
history -r
------------------------- repro 1/2 -------------------------
Finally execute a plain "history", which for me results in
the following output:
------------------------- repro 2/2 -------------------------
bash-5.3$ history
1 2025-04-04 22:09:31 history -r
2 1970-01-01 01:00:01 cat << 'EOF' | wc -l
abc
def
ghi
EOF
3 2025-04-04 22:09:34 history
------------------------- repro 2/2 -------------------------
That is, all the empty lines, most notably those in the here doc
have been skipped by Bash while reading the history.
Fix:
The following patch fixes this bug (if it is one for you):
diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c
index 9a259146..eeae20b1 100644
--- a/lib/readline/histfile.c
+++ b/lib/readline/histfile.c
@@ -415,9 +415,10 @@ read_history_range (const char *filename, int from, int to)
else
*line_end = '\0';
- if (*line_start)
+ /* Process empty lines when reading multiline entries. */
+ if (*line_start || history_multiline_entries)
{
- if (HIST_TIMESTAMP_START(line_start) == 0)
+ if (!*line_start || HIST_TIMESTAMP_START(line_start) == 0)
{
if (last_ts == NULL && history_length > 0 &&
history_multiline_entries)
_hs_append_history_line (history_length - 1, line_start);
Thanks for maintaining Bash!