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!

Reply via email to