documentation updates for history builtin to note it does not truncate the history file; documentation updates for HISTFILESIZE noting that it can work on lines or history entries depending on $HISTTIMEFORMAT; documentation update for history saving behavior at shell exit; history -w and history -a should update the number of history entries in the current session if they are using $HISTFILE; history -r now updates the number of history entries in the current session; improvement to history_truncate_file so it leaves fewer partial history entries when operating on lines

This commit is contained in:
Chet Ramey
2026-08-28 15:35:54 -04:00
parent 71327ab3b5
commit 81ddb6474b
16 changed files with 2086 additions and 1840 deletions
+55
View File
@@ -13261,3 +13261,58 @@ shell.c
`bash -in <<<INPUT' idiom for testing input sequences but
is closer to the documentation and the intent.
Report from Tom Hale <tom@hale.ee>
8/24
----
doc/bash.1,doc/bashref.texi
- HISTFILESIZE: correct description to delete text saying the history
builtin truncates the history file after writing; bash has never
done that.
From https://savannah.gnu.org/bugs/?68641
8/27
----
builtins/history.def
- history_builtin: if we are using $HISTFILE, history -w should
reset history_lines_this_session to 0 to avoid appending duplicate
entries to the history file on shell exit. This should not affect
idioms people use to share a single history file between multiple
shell sessions; most of those use `history -a', which already
resets history_lines_this_session
- history_builtin: if we are using $HISTFILE, history -a should reset
history_lines_this_session to 0
- history_builtin: history -r should increase history_lines_this_session
by the number of lines read from the file, even if it's $HISTFILE
From https://savannah.gnu.org/bugs/index.php?68646
bashhist.c
- maybe_append_history: takes a second argument saying whether or not
we are using $HISTFILE, changed callers
- maybe_append_history: reset history_lines_this_session and
history_lines_in_file only if we are using $HISTFILE
doc/bash.1,lib/readline/doc/hsuser.texi
- make the text describing how bash saves the shell history upon exit
match the actual behavior, making it clear that bash tries to
append the entries from the current session to $HISTFILE and only
overwrites the file if the number of entries from the current
session exceeds $HISTSIZE
From https://savannah.gnu.org/bugs/index.php?68645
lib/readline/histfile.c
- history_truncate_file: use the same heuristic as read_history_range
to determine whether the history file has timestamps, and add 1
to lines even if we're not going by history entries so we (maybe)
get a timestamp before the first line, which we hope is the first
line of a command
doc/bash.1,doc/bashref.texi,lib/readline/doc/hsuser.texi
- update the description of HISTFILESIZE to note that it can refer
to either lines or possibly multi-line history entries depending
on whether HISTTIMEFORMAT is set
- update the history section to describe how HISTTIMEFORMAT affects
how $HISTFILESIZE is interpreted (lines vs. entries) and note that
if we are dealing with lines, there might be more lines than the
maximum in the file to avoid partial history entries or history
entries without a timestamp (if the file has them)
From https://savannah.gnu.org/bugs/?68650
+8 -5
View File
@@ -1,6 +1,6 @@
/* bashhist.c -- bash interface to the GNU history library. */
/* Copyright (C) 1993-2024 Free Software Foundation, Inc.
/* Copyright (C) 1993-2026 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -447,7 +447,7 @@ save_history (void)
#endif
int
maybe_append_history (char *filename)
maybe_append_history (char *filename, int is_histfile)
{
int fd, result, histlen;
struct stat buf;
@@ -471,10 +471,13 @@ maybe_append_history (char *filename)
if (histlen > 0 && history_lines_this_session > histlen)
history_lines_this_session = histlen; /* reset below anyway */
result = append_history (history_lines_this_session, filename);
/* Pretend we already read these lines from the file because we just
/* Pretend we already read these lines from $HISTFILE because we just
added them */
history_lines_in_file += history_lines_this_session;
history_lines_this_session = 0;
if (is_histfile)
{
history_lines_in_file += history_lines_this_session;
history_lines_this_session = 0;
}
}
else
history_lines_this_session = 0; /* reset if > where_history() */
+1 -1
View File
@@ -75,7 +75,7 @@ extern int bash_delete_last_history (void);
extern void load_history (void);
extern void save_history (void);
extern char *bash_default_histfile (void);
extern int maybe_append_history (char *);
extern int maybe_append_history (char *, int);
extern int maybe_save_shell_history (void);
extern char *pre_process_line (char *, int, int);
extern void maybe_add_history (char *);
+30
View File
@@ -1013,6 +1013,36 @@ builtin_find_indexed_array (char *array_name, int flags)
return entry;
}
SHELL_VAR *
builtin_find_array (char *array_name, int flags)
{
SHELL_VAR *entry;
if ((flags & 2) && valid_identifier (array_name) == 0)
{
sh_invalidid (array_name);
return (SHELL_VAR *)NULL;
}
entry = find_or_make_array_variable (array_name, 1);
/* With flags argument & 1, find_or_make_array_variable checks for readonly
and noassign variables and prints error messages. */
if (entry == 0)
return entry;
else if (array_p (entry) == 0 && assoc_p (entry) == 0)
{
builtin_error (_("%s: not an array"), array_name);
return (SHELL_VAR *)NULL;
}
else if (invisible_p (entry))
VUNSETATTR (entry, att_invisible); /* no longer invisible */
if (array_p (entry) && (flags & 1))
array_flush (array_cell (entry));
return entry;
}
#endif /* ARRAY_VARS */
/* Like check_unbind_variable, but for use by builtins (only matters for
+2
View File
@@ -240,6 +240,8 @@ extern SHELL_VAR *builtin_bind_var_to_int (char *, intmax_t, int);
extern int builtin_unbind_variable (const char *);
extern SHELL_VAR *builtin_find_indexed_array (char *, int);
extern SHELL_VAR *builtin_find_array (char *, int);
extern int builtin_arrayref_flags (WORD_DESC *, int);
/* variables from evalfile.c */
+11 -2
View File
@@ -131,7 +131,7 @@ static int expand_and_print_history (WORD_LIST *);
int
history_builtin (WORD_LIST *list)
{
int flags, opt, result, old_history_lines, obase, ind;
int flags, opt, result, old_history_lines, obase, ind, using_histfile;
char *filename, *newfn, *delete_arg, *range;
intmax_t delete_offset;
@@ -266,6 +266,7 @@ history_builtin (WORD_LIST *list)
}
filename = list ? list->word->word : get_string_value ("HISTFILE");
using_histfile = list == NULL;
result = EXECUTION_SUCCESS;
if (filename == 0 || *filename == 0)
@@ -290,7 +291,11 @@ history_builtin (WORD_LIST *list)
#endif
if (flags & AFLAG) /* Append session's history to file. */
result = maybe_append_history (filename);
{
result = maybe_append_history (filename, using_histfile);
if (using_histfile)
history_lines_this_session = 0;
}
else if (flags & WFLAG) /* Write entire history. */
{
result = write_history (filename);
@@ -299,6 +304,8 @@ history_builtin (WORD_LIST *list)
I/O and permission errors. */
if (result > 0)
history_error (filename, result, 0);
if (result == 0 && using_histfile)
history_lines_this_session = 0;
}
else if (flags & RFLAG) /* Read entire file. */
{
@@ -310,6 +317,8 @@ history_builtin (WORD_LIST *list)
I/O and permission errors. */
if (result > 0)
history_error (filename, result, 1);
if (result == 0)
history_lines_this_session += history_lines_read_from_file;
}
else if (flags & NFLAG) /* Read `new' history from file. */
{
+4
View File
@@ -162,6 +162,10 @@ mapfile (int fd, long line_count_goal, long origin, long nskip, long callback_qu
/* If the delimiter is a newline, turn on unbuffered reads for pipes
(terminals are ok). If the delimiter is not a newline, unbuffered reads
for every file descriptor that's not a regular file. */
/* We could check that the delimiter is a newline and the input is a
terminal and force buffered reads in that case, letting the kernel find
the newline for us, or set the VISABLE character like the read builtin
does and let the kernel detect it. */
if (delim == '\n')
unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
else
+1502 -1488
View File
File diff suppressed because it is too large Load Diff
+58 -18
View File
@@ -5,7 +5,7 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Thu Aug 20 11:41:54 EDT 2026
.\" Last Change: Thu Aug 27 12:59:58 EDT 2026
.\"
.\" For bash_builtins, strip all but "SHELL BUILTIN COMMANDS" section
.\" For rbash, strip all but "RESTRICTED SHELL" section
@@ -22,7 +22,7 @@
.ds zX \" empty
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2026 August 20" "GNU Bash 5.4"
.TH BASH 1 "2026 August 27" "GNU Bash 5.4"
.\"
.ie \n(.g \{\
.ds ' \(aq
@@ -2707,19 +2707,23 @@ is unset or null,
the shell does not save the command history when it exits.
.TP
.B HISTFILESIZE
The maximum number of lines contained in the history file.
The maximum number of lines or history entries contained in the history file.
When this variable is assigned a value, the history file is truncated,
if necessary, to contain no more than
the number of history entries
that total no more than that number of lines
by removing the oldest entries.
If the history list contains multi-line entries,
the history file may contain more lines than this maximum
to avoid leaving partial history entries.
the number of history entries or lines,
depending on whether
.B HISTTIMEFORMAT
is set, by removing the oldest entries.
See
.SM
.B HISTORY
below
for a description of how
.B HISTTIMEFORMAT
affects how the value is treated and
whether it refers to lines or history entries.
The history file is also truncated to this size after
writing it when a shell exits or by the
.B \%history
builtin.
writing it when a shell exits.
If the value is 0, the history file is truncated to zero size.
Non-numeric values and numeric values less than zero inhibit truncation.
The shell sets the default value to the value of
@@ -8723,11 +8727,34 @@ variable (default
.FN \*~/.bash_history ).
That file is referred to as the \fIhistory file\fP.
The history file is truncated, if necessary,
to contain no more than the number of history entries
to contain no more than the number of lines or
history entries
specified by the value of the
.SM
.B HISTFILESIZE
variable.
.PP
The value of
.B HISTFILESIZE
is interpreted as lines or possibly multi-line history
entries depending on whether the
.B HISTTIMEFORMAT
variable has a value,
since that controls whether or not timestamps are written
to the history file.
If
.B HISTTIMEFORMAT
has a value,
.B HISTFILESIZE
is interpreted as a number of
history entries, including timestamps.
If it does not,
.B HISTFILESIZE
is interpreted as a number of lines,
which may result in incomplete history entries in the history file,
or the history file containing more lines than this maximum
to avoid leaving partial history entries.
.PP
If
.SM
.B HISTFILESIZE
@@ -8744,10 +8771,12 @@ variable.
When present, history timestamps delimit history entries, making
multi-line entries possible.
.PP
When a shell with history enabled exits, \fBbash\fP copies the last
When a shell with history enabled exits, \fBbash\fP
copies up to the last
.SM
.B $HISTSIZE
entries from the history list to
the file named by
.SM
.BR $HISTFILE .
If the
@@ -8758,8 +8787,18 @@ shell option is enabled
under
.SM
.B "SHELL BUILTIN COMMANDS"
below), \fBbash\fP appends the entries to the history file,
otherwise it overwrites the history file.
below),
or if the number of history entries entered
during the current shell session is not greater than
.BR $HISTSIZE ,
\fBbash\fP appends the entries entered during the current session to
.BR $HISTFILE .
If
.B histappend
is not set, and the number of entries from the current
shell session exceeds
.BR $HISTSIZE ,
it overwrites the history file with the entries from the current session.
If
.SM
.B HISTFILE
@@ -8769,7 +8808,7 @@ After saving the history, \fBbash\fP truncates the history file
to contain no more than
.SM
.B HISTFILESIZE
lines as described above.
entries as described above.
.PP
If the
.SM
@@ -12404,7 +12443,8 @@ If set, the history list is appended to the file named by the value
of the
.SM
.B HISTFILE
variable when the shell exits, rather than overwriting the file.
variable when the shell exits, rather than
potentially overwriting the file.
.TP 8
.B histreedit
If set, and
+165 -147
View File
@@ -1,9 +1,9 @@
This is bash.info, produced by makeinfo version 7.3 from bashref.texi.
This text is a brief description of the features that are present in the
Bash shell (version 5.4, 20 August 2026).
Bash shell (version 5.4, 27 August 2026).
This is Edition 5.4, last updated 20 August 2026, of The GNU Bash
This is Edition 5.4, last updated 27 August 2026, of The GNU Bash
Reference Manual, for Bash, Version 5.4.
Copyright © 1988-2026 Free Software Foundation, Inc.
@@ -26,10 +26,10 @@ Bash Features
*************
This text is a brief description of the features that are present in the
Bash shell (version 5.4, 20 August 2026). The Bash home page is
Bash shell (version 5.4, 27 August 2026). The Bash home page is
<http://www.gnu.org/software/bash/>.
This is Edition 5.4, last updated 20 August 2026, of The GNU Bash
This is Edition 5.4, last updated 27 August 2026, of The GNU Bash
Reference Manual, for Bash, Version 5.4.
Bash contains features that appear in other popular shells, and some
@@ -5430,7 +5430,7 @@ This builtin allows you to change additional optional shell behavior.
histappend
If set, the history list is appended to the file named by the
value of the HISTFILE variable when the shell exits, rather
than overwriting the file.
than potentially overwriting the file.
histreedit
If set, and Readline is being used, the user is given the
@@ -6161,15 +6161,18 @@ Variables::).
exits.
HISTFILESIZE
The maximum number of lines contained in the history file. When
this variable is assigned a value, the history file is truncated,
if necessary, to contain no more than the number of history entries
that total no more than that number of lines by removing the oldest
entries. If the history list contains multi-line entries, the
history file may contain more lines than this maximum to avoid
leaving partial history entries. The history file is also
truncated to this size after writing it when a shell exits or by
the history builtin. If the value is 0, the history file is
The maximum number of lines or history entries contained in the
history file. When this variable is assigned a value, the history
file is truncated, if necessary, to contain no more than that
number of history entries or lines, depending on the value of
HISTTIMEFORMAT, by removing the oldest entries.
*Note Bash History Facilities::, for a description of how
HISTTIMEFORMAT affects how the value is treated and whether it
refers to lines or history entries.
The history file is also truncated to this size after writing it
when a shell exits. If the value is 0, the history file is
truncated to zero size. Non-numeric values and numeric values less
than zero inhibit truncation. The shell sets the default value to
the value of HISTSIZE after reading any startup files.
@@ -11012,10 +11015,21 @@ the values of the shell variables HISTIGNORE and HISTCONTROL.
reading history entries from the file named by the HISTFILE variable
(default ~/.bash_history). This is referred to as the “history file”.
The history file is truncated, if necessary, to contain no more than the
number of history entries specified by the value of the HISTFILESIZE
variable. If HISTFILESIZE is unset, or set to null, a non-numeric
value, or a numeric value less than zero, the history file is not
truncated.
number of lines or history entries specified by the value of the
HISTFILESIZE variable.
The value of HISTFILESIZE is interpreted as lines or possibly
multi-line history entries depending on whether the HISTTIMEFORMAT
variable has a value, since that controls whether or not timestamps are
written to the history file. If HISTTIMEFORMAT has a value,
HISTFILESIZE is interpreted as a number of history entries, including
timestamps. If it does not, HISTFILESIZE is interpreted as a number
of lines, which may result in incomplete history entries in the history
file, or the history file containing more lines than this maximum to
avoid leaving partial history entries.
If HISTFILESIZE is unset, or set to null, a non-numeric value, or a
numeric value less than zero, the history file is not truncated.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted as
@@ -11024,14 +11038,18 @@ optionally displayed depending on the value of the HISTTIMEFORMAT
variable (*note Bash Variables::). When present, history timestamps
delimit history entries, making multi-line entries possible.
When a shell with history enabled exits, Bash copies the last
When a shell with history enabled exits, Bash copies up to the last
$HISTSIZE entries from the history list to the file named by
$HISTFILE. If the histappend shell option is set (*note Bash
Builtins::), Bash appends the entries to the history file, otherwise it
overwrites the history file. If HISTFILE is unset or null, or if the
history file is unwritable, the history is not saved. After saving the
history, Bash truncates the history file to contain no more than
$HISTFILESIZE lines as described above.
Builtins::), or if the number of history entries entered during the
current shell session is less than $HISTSIZE, Bash appends the history
entries entered during the current session to $HISTFILE. If
histappend is not set, and the number of entries from the current
shell session exceeds $HISTSIZE, it overwrites the history file with
the entries from the current session. If HISTFILE is unset or null,
or if the history file is unwritable, the history is not saved. After
saving the history, Bash truncates the history file to contain no more
than $HISTFILESIZE entries as described above.
If the HISTTIMEFORMAT variable is set, the shell writes the
timestamp information associated with each history entry to the history
@@ -13294,51 +13312,51 @@ D.3 Parameter and Variable Index
* HISTCONTROL: Bash Variables. (line 445)
* HISTFILE: Bash Variables. (line 463)
* HISTFILESIZE: Bash Variables. (line 469)
* HISTIGNORE: Bash Variables. (line 483)
* HISTIGNORE: Bash Variables. (line 486)
* history-preserve-point: Readline Init File Syntax.
(line 236)
* history-size: Readline Init File Syntax.
(line 242)
* HISTSIZE: Bash Variables. (line 507)
* HISTTIMEFORMAT: Bash Variables. (line 514)
* HISTSIZE: Bash Variables. (line 510)
* HISTTIMEFORMAT: Bash Variables. (line 517)
* HOME: Bourne Shell Variables.
(line 13)
* horizontal-scroll-mode: Readline Init File Syntax.
(line 252)
* HOSTFILE: Bash Variables. (line 523)
* HOSTNAME: Bash Variables. (line 534)
* HOSTTYPE: Bash Variables. (line 537)
* HOSTFILE: Bash Variables. (line 526)
* HOSTNAME: Bash Variables. (line 537)
* HOSTTYPE: Bash Variables. (line 540)
* IFS: Bourne Shell Variables.
(line 18)
* IGNOREEOF: Bash Variables. (line 540)
* IGNOREEOF: Bash Variables. (line 543)
* input-meta: Readline Init File Syntax.
(line 260)
* INPUTRC: Bash Variables. (line 549)
* INSIDE_EMACS: Bash Variables. (line 553)
* INPUTRC: Bash Variables. (line 552)
* INSIDE_EMACS: Bash Variables. (line 556)
* isearch-terminators: Readline Init File Syntax.
(line 271)
* keymap: Readline Init File Syntax.
(line 278)
* LANG: Creating Internationalized Scripts.
(line 51)
* LANG <1>: Bash Variables. (line 559)
* LC_ALL: Bash Variables. (line 563)
* LC_COLLATE: Bash Variables. (line 567)
* LC_CTYPE: Bash Variables. (line 574)
* LANG <1>: Bash Variables. (line 562)
* LC_ALL: Bash Variables. (line 566)
* LC_COLLATE: Bash Variables. (line 570)
* LC_CTYPE: Bash Variables. (line 577)
* LC_MESSAGES: Creating Internationalized Scripts.
(line 51)
* LC_MESSAGES <1>: Bash Variables. (line 579)
* LC_NUMERIC: Bash Variables. (line 583)
* LC_TIME: Bash Variables. (line 587)
* LINENO: Bash Variables. (line 591)
* LINES: Bash Variables. (line 598)
* MACHTYPE: Bash Variables. (line 604)
* LC_MESSAGES <1>: Bash Variables. (line 582)
* LC_NUMERIC: Bash Variables. (line 586)
* LC_TIME: Bash Variables. (line 590)
* LINENO: Bash Variables. (line 594)
* LINES: Bash Variables. (line 601)
* MACHTYPE: Bash Variables. (line 607)
* MAIL: Bourne Shell Variables.
(line 24)
* MAILCHECK: Bash Variables. (line 608)
* MAILCHECK: Bash Variables. (line 611)
* MAILPATH: Bourne Shell Variables.
(line 29)
* MAPFILE: Bash Variables. (line 616)
* MAPFILE: Bash Variables. (line 619)
* mark-modified-lines: Readline Init File Syntax.
(line 308)
* mark-symlinked-directories: Readline Init File Syntax.
@@ -13349,46 +13367,46 @@ D.3 Parameter and Variable Index
(line 325)
* meta-flag: Readline Init File Syntax.
(line 260)
* OLDPWD: Bash Variables. (line 620)
* OLDPWD: Bash Variables. (line 623)
* OPTARG: Bourne Shell Variables.
(line 36)
* OPTERR: Bash Variables. (line 623)
* OPTERR: Bash Variables. (line 626)
* OPTIND: Bourne Shell Variables.
(line 40)
* OSTYPE: Bash Variables. (line 628)
* OSTYPE: Bash Variables. (line 631)
* output-meta: Readline Init File Syntax.
(line 330)
* page-completions: Readline Init File Syntax.
(line 339)
* PATH: Bourne Shell Variables.
(line 44)
* PIPESTATUS: Bash Variables. (line 631)
* POSIXLY_CORRECT: Bash Variables. (line 641)
* PPID: Bash Variables. (line 651)
* PROMPT_COMMAND: Bash Variables. (line 655)
* PROMPT_DIRTRIM: Bash Variables. (line 661)
* PS0: Bash Variables. (line 667)
* PIPESTATUS: Bash Variables. (line 634)
* POSIXLY_CORRECT: Bash Variables. (line 644)
* PPID: Bash Variables. (line 654)
* PROMPT_COMMAND: Bash Variables. (line 658)
* PROMPT_DIRTRIM: Bash Variables. (line 664)
* PS0: Bash Variables. (line 670)
* PS1: Bourne Shell Variables.
(line 53)
* PS2: Bourne Shell Variables.
(line 58)
* PS3: Bash Variables. (line 672)
* PS4: Bash Variables. (line 677)
* PWD: Bash Variables. (line 685)
* RANDOM: Bash Variables. (line 688)
* READLINE_ARGUMENT: Bash Variables. (line 696)
* READLINE_LINE: Bash Variables. (line 700)
* READLINE_MARK: Bash Variables. (line 704)
* READLINE_POINT: Bash Variables. (line 710)
* REPLY: Bash Variables. (line 714)
* PS3: Bash Variables. (line 675)
* PS4: Bash Variables. (line 680)
* PWD: Bash Variables. (line 688)
* RANDOM: Bash Variables. (line 691)
* READLINE_ARGUMENT: Bash Variables. (line 699)
* READLINE_LINE: Bash Variables. (line 703)
* READLINE_MARK: Bash Variables. (line 707)
* READLINE_POINT: Bash Variables. (line 713)
* REPLY: Bash Variables. (line 717)
* revert-all-at-newline: Readline Init File Syntax.
(line 352)
* search-ignore-case: Readline Init File Syntax.
(line 359)
* SECONDS: Bash Variables. (line 718)
* SHELL: Bash Variables. (line 728)
* SHELLOPTS: Bash Variables. (line 733)
* SHLVL: Bash Variables. (line 743)
* SECONDS: Bash Variables. (line 721)
* SHELL: Bash Variables. (line 731)
* SHELLOPTS: Bash Variables. (line 736)
* SHLVL: Bash Variables. (line 746)
* show-all-if-ambiguous: Readline Init File Syntax.
(line 364)
* show-all-if-unmodified: Readline Init File Syntax.
@@ -13397,15 +13415,15 @@ D.3 Parameter and Variable Index
(line 379)
* skip-completed-text: Readline Init File Syntax.
(line 385)
* SRANDOM: Bash Variables. (line 748)
* SRANDOM: Bash Variables. (line 751)
* TEXTDOMAIN: Creating Internationalized Scripts.
(line 51)
* TEXTDOMAINDIR: Creating Internationalized Scripts.
(line 51)
* TIMEFORMAT: Bash Variables. (line 757)
* TMOUT: Bash Variables. (line 796)
* TMPDIR: Bash Variables. (line 808)
* UID: Bash Variables. (line 812)
* TIMEFORMAT: Bash Variables. (line 760)
* TMOUT: Bash Variables. (line 799)
* TMPDIR: Bash Variables. (line 811)
* UID: Bash Variables. (line 815)
* vi-cmd-mode-string: Readline Init File Syntax.
(line 398)
* vi-ins-mode-string: Readline Init File Syntax.
@@ -13862,81 +13880,81 @@ Node: Bash Builtins182353
Node: Modifying Shell Behavior220088
Node: The Set Builtin220430
Node: The Shopt Builtin232556
Node: Special Builtins250092
Node: Shell Variables251081
Node: Bourne Shell Variables251515
Node: Bash Variables254023
Node: Bash Features293307
Node: Invoking Bash294321
Node: Bash Startup Files301551
Node: Interactive Shells306911
Node: What is an Interactive Shell?307319
Node: Is this Shell Interactive?307981
Node: Interactive Shell Behavior308805
Node: Bash Conditional Expressions312566
Node: Shell Arithmetic317983
Node: Aliases321310
Node: Arrays324444
Node: The Directory Stack332547
Node: Directory Stack Builtins333344
Node: Controlling the Prompt337789
Node: The Restricted Shell340908
Node: Bash POSIX Mode344001
Node: Shell Compatibility Mode363960
Node: Job Control372967
Node: Job Control Basics373424
Node: Job Control Builtins379792
Node: Job Control Variables386580
Node: Command Line Editing387811
Node: Introduction and Notation389514
Node: Readline Interaction391866
Node: Readline Bare Essentials393054
Node: Readline Movement Commands394862
Node: Readline Killing Commands395858
Node: Readline Arguments397881
Node: Searching398971
Node: Readline Init File401214
Node: Readline Init File Syntax402517
Node: Conditional Init Constructs429468
Node: Sample Init File433853
Node: Bindable Readline Commands436973
Node: Commands For Moving438511
Node: Commands For History440975
Node: Commands For Text447132
Node: Commands For Killing451257
Node: Numeric Arguments454045
Node: Commands For Completion455197
Node: Keyboard Macros460893
Node: Miscellaneous Commands461594
Node: Readline vi Mode469137
Node: Programmable Completion470114
Node: Programmable Completion Builtins479850
Node: A Programmable Completion Example491587
Node: Using History Interactively496932
Node: Bash History Facilities497613
Node: Bash History Builtins501348
Node: History Interaction508943
Node: Event Designators513893
Node: Word Designators515471
Node: Modifiers517863
Node: Installing Bash519800
Node: Basic Installation520916
Node: Compilers and Options524792
Node: Compiling For Multiple Architectures525542
Node: Installation Names527295
Node: Specifying the System Type529529
Node: Sharing Defaults530275
Node: Operation Controls530989
Node: Optional Features532008
Node: Reporting Bugs544731
Node: Major Differences From The Bourne Shell546088
Node: GNU Free Documentation License567515
Node: Indexes592692
Node: Builtin Index593143
Node: Reserved Word Index600241
Node: Variable Index602686
Node: Function Index620099
Node: Concept Index634524
Node: Special Builtins250104
Node: Shell Variables251093
Node: Bourne Shell Variables251527
Node: Bash Variables254035
Node: Bash Features293339
Node: Invoking Bash294353
Node: Bash Startup Files301583
Node: Interactive Shells306943
Node: What is an Interactive Shell?307351
Node: Is this Shell Interactive?308013
Node: Interactive Shell Behavior308837
Node: Bash Conditional Expressions312598
Node: Shell Arithmetic318015
Node: Aliases321342
Node: Arrays324476
Node: The Directory Stack332579
Node: Directory Stack Builtins333376
Node: Controlling the Prompt337821
Node: The Restricted Shell340940
Node: Bash POSIX Mode344033
Node: Shell Compatibility Mode363992
Node: Job Control372999
Node: Job Control Basics373456
Node: Job Control Builtins379824
Node: Job Control Variables386612
Node: Command Line Editing387843
Node: Introduction and Notation389546
Node: Readline Interaction391898
Node: Readline Bare Essentials393086
Node: Readline Movement Commands394894
Node: Readline Killing Commands395890
Node: Readline Arguments397913
Node: Searching399003
Node: Readline Init File401246
Node: Readline Init File Syntax402549
Node: Conditional Init Constructs429500
Node: Sample Init File433885
Node: Bindable Readline Commands437005
Node: Commands For Moving438543
Node: Commands For History441007
Node: Commands For Text447164
Node: Commands For Killing451289
Node: Numeric Arguments454077
Node: Commands For Completion455229
Node: Keyboard Macros460925
Node: Miscellaneous Commands461626
Node: Readline vi Mode469169
Node: Programmable Completion470146
Node: Programmable Completion Builtins479882
Node: A Programmable Completion Example491619
Node: Using History Interactively496964
Node: Bash History Facilities497645
Node: Bash History Builtins502311
Node: History Interaction509906
Node: Event Designators514856
Node: Word Designators516434
Node: Modifiers518826
Node: Installing Bash520763
Node: Basic Installation521879
Node: Compilers and Options525755
Node: Compiling For Multiple Architectures526505
Node: Installation Names528258
Node: Specifying the System Type530492
Node: Sharing Defaults531238
Node: Operation Controls531952
Node: Optional Features532971
Node: Reporting Bugs545694
Node: Major Differences From The Bourne Shell547051
Node: GNU Free Documentation License568478
Node: Indexes593655
Node: Builtin Index594106
Node: Reserved Word Index601204
Node: Variable Index603649
Node: Function Index621062
Node: Concept Index635487

End Tag Table
+165 -147
View File
@@ -2,9 +2,9 @@ This is bashref.info, produced by makeinfo version 7.3 from
bashref.texi.
This text is a brief description of the features that are present in the
Bash shell (version 5.4, 20 August 2026).
Bash shell (version 5.4, 27 August 2026).
This is Edition 5.4, last updated 20 August 2026, of The GNU Bash
This is Edition 5.4, last updated 27 August 2026, of The GNU Bash
Reference Manual, for Bash, Version 5.4.
Copyright © 1988-2026 Free Software Foundation, Inc.
@@ -27,10 +27,10 @@ Bash Features
*************
This text is a brief description of the features that are present in the
Bash shell (version 5.4, 20 August 2026). The Bash home page is
Bash shell (version 5.4, 27 August 2026). The Bash home page is
<http://www.gnu.org/software/bash/>.
This is Edition 5.4, last updated 20 August 2026, of The GNU Bash
This is Edition 5.4, last updated 27 August 2026, of The GNU Bash
Reference Manual, for Bash, Version 5.4.
Bash contains features that appear in other popular shells, and some
@@ -5431,7 +5431,7 @@ This builtin allows you to change additional optional shell behavior.
histappend
If set, the history list is appended to the file named by the
value of the HISTFILE variable when the shell exits, rather
than overwriting the file.
than potentially overwriting the file.
histreedit
If set, and Readline is being used, the user is given the
@@ -6162,15 +6162,18 @@ Variables::).
exits.
HISTFILESIZE
The maximum number of lines contained in the history file. When
this variable is assigned a value, the history file is truncated,
if necessary, to contain no more than the number of history entries
that total no more than that number of lines by removing the oldest
entries. If the history list contains multi-line entries, the
history file may contain more lines than this maximum to avoid
leaving partial history entries. The history file is also
truncated to this size after writing it when a shell exits or by
the history builtin. If the value is 0, the history file is
The maximum number of lines or history entries contained in the
history file. When this variable is assigned a value, the history
file is truncated, if necessary, to contain no more than that
number of history entries or lines, depending on the value of
HISTTIMEFORMAT, by removing the oldest entries.
*Note Bash History Facilities::, for a description of how
HISTTIMEFORMAT affects how the value is treated and whether it
refers to lines or history entries.
The history file is also truncated to this size after writing it
when a shell exits. If the value is 0, the history file is
truncated to zero size. Non-numeric values and numeric values less
than zero inhibit truncation. The shell sets the default value to
the value of HISTSIZE after reading any startup files.
@@ -11013,10 +11016,21 @@ the values of the shell variables HISTIGNORE and HISTCONTROL.
reading history entries from the file named by the HISTFILE variable
(default ~/.bash_history). This is referred to as the “history file”.
The history file is truncated, if necessary, to contain no more than the
number of history entries specified by the value of the HISTFILESIZE
variable. If HISTFILESIZE is unset, or set to null, a non-numeric
value, or a numeric value less than zero, the history file is not
truncated.
number of lines or history entries specified by the value of the
HISTFILESIZE variable.
The value of HISTFILESIZE is interpreted as lines or possibly
multi-line history entries depending on whether the HISTTIMEFORMAT
variable has a value, since that controls whether or not timestamps are
written to the history file. If HISTTIMEFORMAT has a value,
HISTFILESIZE is interpreted as a number of history entries, including
timestamps. If it does not, HISTFILESIZE is interpreted as a number
of lines, which may result in incomplete history entries in the history
file, or the history file containing more lines than this maximum to
avoid leaving partial history entries.
If HISTFILESIZE is unset, or set to null, a non-numeric value, or a
numeric value less than zero, the history file is not truncated.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted as
@@ -11025,14 +11039,18 @@ optionally displayed depending on the value of the HISTTIMEFORMAT
variable (*note Bash Variables::). When present, history timestamps
delimit history entries, making multi-line entries possible.
When a shell with history enabled exits, Bash copies the last
When a shell with history enabled exits, Bash copies up to the last
$HISTSIZE entries from the history list to the file named by
$HISTFILE. If the histappend shell option is set (*note Bash
Builtins::), Bash appends the entries to the history file, otherwise it
overwrites the history file. If HISTFILE is unset or null, or if the
history file is unwritable, the history is not saved. After saving the
history, Bash truncates the history file to contain no more than
$HISTFILESIZE lines as described above.
Builtins::), or if the number of history entries entered during the
current shell session is less than $HISTSIZE, Bash appends the history
entries entered during the current session to $HISTFILE. If
histappend is not set, and the number of entries from the current
shell session exceeds $HISTSIZE, it overwrites the history file with
the entries from the current session. If HISTFILE is unset or null,
or if the history file is unwritable, the history is not saved. After
saving the history, Bash truncates the history file to contain no more
than $HISTFILESIZE entries as described above.
If the HISTTIMEFORMAT variable is set, the shell writes the
timestamp information associated with each history entry to the history
@@ -13295,51 +13313,51 @@ D.3 Parameter and Variable Index
* HISTCONTROL: Bash Variables. (line 445)
* HISTFILE: Bash Variables. (line 463)
* HISTFILESIZE: Bash Variables. (line 469)
* HISTIGNORE: Bash Variables. (line 483)
* HISTIGNORE: Bash Variables. (line 486)
* history-preserve-point: Readline Init File Syntax.
(line 236)
* history-size: Readline Init File Syntax.
(line 242)
* HISTSIZE: Bash Variables. (line 507)
* HISTTIMEFORMAT: Bash Variables. (line 514)
* HISTSIZE: Bash Variables. (line 510)
* HISTTIMEFORMAT: Bash Variables. (line 517)
* HOME: Bourne Shell Variables.
(line 13)
* horizontal-scroll-mode: Readline Init File Syntax.
(line 252)
* HOSTFILE: Bash Variables. (line 523)
* HOSTNAME: Bash Variables. (line 534)
* HOSTTYPE: Bash Variables. (line 537)
* HOSTFILE: Bash Variables. (line 526)
* HOSTNAME: Bash Variables. (line 537)
* HOSTTYPE: Bash Variables. (line 540)
* IFS: Bourne Shell Variables.
(line 18)
* IGNOREEOF: Bash Variables. (line 540)
* IGNOREEOF: Bash Variables. (line 543)
* input-meta: Readline Init File Syntax.
(line 260)
* INPUTRC: Bash Variables. (line 549)
* INSIDE_EMACS: Bash Variables. (line 553)
* INPUTRC: Bash Variables. (line 552)
* INSIDE_EMACS: Bash Variables. (line 556)
* isearch-terminators: Readline Init File Syntax.
(line 271)
* keymap: Readline Init File Syntax.
(line 278)
* LANG: Creating Internationalized Scripts.
(line 51)
* LANG <1>: Bash Variables. (line 559)
* LC_ALL: Bash Variables. (line 563)
* LC_COLLATE: Bash Variables. (line 567)
* LC_CTYPE: Bash Variables. (line 574)
* LANG <1>: Bash Variables. (line 562)
* LC_ALL: Bash Variables. (line 566)
* LC_COLLATE: Bash Variables. (line 570)
* LC_CTYPE: Bash Variables. (line 577)
* LC_MESSAGES: Creating Internationalized Scripts.
(line 51)
* LC_MESSAGES <1>: Bash Variables. (line 579)
* LC_NUMERIC: Bash Variables. (line 583)
* LC_TIME: Bash Variables. (line 587)
* LINENO: Bash Variables. (line 591)
* LINES: Bash Variables. (line 598)
* MACHTYPE: Bash Variables. (line 604)
* LC_MESSAGES <1>: Bash Variables. (line 582)
* LC_NUMERIC: Bash Variables. (line 586)
* LC_TIME: Bash Variables. (line 590)
* LINENO: Bash Variables. (line 594)
* LINES: Bash Variables. (line 601)
* MACHTYPE: Bash Variables. (line 607)
* MAIL: Bourne Shell Variables.
(line 24)
* MAILCHECK: Bash Variables. (line 608)
* MAILCHECK: Bash Variables. (line 611)
* MAILPATH: Bourne Shell Variables.
(line 29)
* MAPFILE: Bash Variables. (line 616)
* MAPFILE: Bash Variables. (line 619)
* mark-modified-lines: Readline Init File Syntax.
(line 308)
* mark-symlinked-directories: Readline Init File Syntax.
@@ -13350,46 +13368,46 @@ D.3 Parameter and Variable Index
(line 325)
* meta-flag: Readline Init File Syntax.
(line 260)
* OLDPWD: Bash Variables. (line 620)
* OLDPWD: Bash Variables. (line 623)
* OPTARG: Bourne Shell Variables.
(line 36)
* OPTERR: Bash Variables. (line 623)
* OPTERR: Bash Variables. (line 626)
* OPTIND: Bourne Shell Variables.
(line 40)
* OSTYPE: Bash Variables. (line 628)
* OSTYPE: Bash Variables. (line 631)
* output-meta: Readline Init File Syntax.
(line 330)
* page-completions: Readline Init File Syntax.
(line 339)
* PATH: Bourne Shell Variables.
(line 44)
* PIPESTATUS: Bash Variables. (line 631)
* POSIXLY_CORRECT: Bash Variables. (line 641)
* PPID: Bash Variables. (line 651)
* PROMPT_COMMAND: Bash Variables. (line 655)
* PROMPT_DIRTRIM: Bash Variables. (line 661)
* PS0: Bash Variables. (line 667)
* PIPESTATUS: Bash Variables. (line 634)
* POSIXLY_CORRECT: Bash Variables. (line 644)
* PPID: Bash Variables. (line 654)
* PROMPT_COMMAND: Bash Variables. (line 658)
* PROMPT_DIRTRIM: Bash Variables. (line 664)
* PS0: Bash Variables. (line 670)
* PS1: Bourne Shell Variables.
(line 53)
* PS2: Bourne Shell Variables.
(line 58)
* PS3: Bash Variables. (line 672)
* PS4: Bash Variables. (line 677)
* PWD: Bash Variables. (line 685)
* RANDOM: Bash Variables. (line 688)
* READLINE_ARGUMENT: Bash Variables. (line 696)
* READLINE_LINE: Bash Variables. (line 700)
* READLINE_MARK: Bash Variables. (line 704)
* READLINE_POINT: Bash Variables. (line 710)
* REPLY: Bash Variables. (line 714)
* PS3: Bash Variables. (line 675)
* PS4: Bash Variables. (line 680)
* PWD: Bash Variables. (line 688)
* RANDOM: Bash Variables. (line 691)
* READLINE_ARGUMENT: Bash Variables. (line 699)
* READLINE_LINE: Bash Variables. (line 703)
* READLINE_MARK: Bash Variables. (line 707)
* READLINE_POINT: Bash Variables. (line 713)
* REPLY: Bash Variables. (line 717)
* revert-all-at-newline: Readline Init File Syntax.
(line 352)
* search-ignore-case: Readline Init File Syntax.
(line 359)
* SECONDS: Bash Variables. (line 718)
* SHELL: Bash Variables. (line 728)
* SHELLOPTS: Bash Variables. (line 733)
* SHLVL: Bash Variables. (line 743)
* SECONDS: Bash Variables. (line 721)
* SHELL: Bash Variables. (line 731)
* SHELLOPTS: Bash Variables. (line 736)
* SHLVL: Bash Variables. (line 746)
* show-all-if-ambiguous: Readline Init File Syntax.
(line 364)
* show-all-if-unmodified: Readline Init File Syntax.
@@ -13398,15 +13416,15 @@ D.3 Parameter and Variable Index
(line 379)
* skip-completed-text: Readline Init File Syntax.
(line 385)
* SRANDOM: Bash Variables. (line 748)
* SRANDOM: Bash Variables. (line 751)
* TEXTDOMAIN: Creating Internationalized Scripts.
(line 51)
* TEXTDOMAINDIR: Creating Internationalized Scripts.
(line 51)
* TIMEFORMAT: Bash Variables. (line 757)
* TMOUT: Bash Variables. (line 796)
* TMPDIR: Bash Variables. (line 808)
* UID: Bash Variables. (line 812)
* TIMEFORMAT: Bash Variables. (line 760)
* TMOUT: Bash Variables. (line 799)
* TMPDIR: Bash Variables. (line 811)
* UID: Bash Variables. (line 815)
* vi-cmd-mode-string: Readline Init File Syntax.
(line 398)
* vi-ins-mode-string: Readline Init File Syntax.
@@ -13863,81 +13881,81 @@ Node: Bash Builtins182515
Node: Modifying Shell Behavior220253
Node: The Set Builtin220598
Node: The Shopt Builtin232727
Node: Special Builtins250266
Node: Shell Variables251258
Node: Bourne Shell Variables251695
Node: Bash Variables254206
Node: Bash Features293493
Node: Invoking Bash294510
Node: Bash Startup Files301743
Node: Interactive Shells307106
Node: What is an Interactive Shell?307517
Node: Is this Shell Interactive?308182
Node: Interactive Shell Behavior309009
Node: Bash Conditional Expressions312773
Node: Shell Arithmetic318193
Node: Aliases321523
Node: Arrays324660
Node: The Directory Stack332766
Node: Directory Stack Builtins333566
Node: Controlling the Prompt338014
Node: The Restricted Shell341136
Node: Bash POSIX Mode344232
Node: Shell Compatibility Mode364194
Node: Job Control373204
Node: Job Control Basics373664
Node: Job Control Builtins380035
Node: Job Control Variables386826
Node: Command Line Editing388060
Node: Introduction and Notation389766
Node: Readline Interaction392121
Node: Readline Bare Essentials393312
Node: Readline Movement Commands395123
Node: Readline Killing Commands396122
Node: Readline Arguments398148
Node: Searching399241
Node: Readline Init File401487
Node: Readline Init File Syntax402793
Node: Conditional Init Constructs429747
Node: Sample Init File434135
Node: Bindable Readline Commands437258
Node: Commands For Moving438799
Node: Commands For History441266
Node: Commands For Text447426
Node: Commands For Killing451554
Node: Numeric Arguments454345
Node: Commands For Completion455500
Node: Keyboard Macros461199
Node: Miscellaneous Commands461903
Node: Readline vi Mode469449
Node: Programmable Completion470429
Node: Programmable Completion Builtins480168
Node: A Programmable Completion Example491908
Node: Using History Interactively497256
Node: Bash History Facilities497940
Node: Bash History Builtins501678
Node: History Interaction509276
Node: Event Designators514229
Node: Word Designators515810
Node: Modifiers518205
Node: Installing Bash520145
Node: Basic Installation521264
Node: Compilers and Options525143
Node: Compiling For Multiple Architectures525896
Node: Installation Names527652
Node: Specifying the System Type529889
Node: Sharing Defaults530638
Node: Operation Controls531355
Node: Optional Features532377
Node: Reporting Bugs545103
Node: Major Differences From The Bourne Shell546463
Node: GNU Free Documentation License567893
Node: Indexes593073
Node: Builtin Index593527
Node: Reserved Word Index600628
Node: Variable Index603076
Node: Function Index620492
Node: Concept Index634920
Node: Special Builtins250278
Node: Shell Variables251270
Node: Bourne Shell Variables251707
Node: Bash Variables254218
Node: Bash Features293525
Node: Invoking Bash294542
Node: Bash Startup Files301775
Node: Interactive Shells307138
Node: What is an Interactive Shell?307549
Node: Is this Shell Interactive?308214
Node: Interactive Shell Behavior309041
Node: Bash Conditional Expressions312805
Node: Shell Arithmetic318225
Node: Aliases321555
Node: Arrays324692
Node: The Directory Stack332798
Node: Directory Stack Builtins333598
Node: Controlling the Prompt338046
Node: The Restricted Shell341168
Node: Bash POSIX Mode344264
Node: Shell Compatibility Mode364226
Node: Job Control373236
Node: Job Control Basics373696
Node: Job Control Builtins380067
Node: Job Control Variables386858
Node: Command Line Editing388092
Node: Introduction and Notation389798
Node: Readline Interaction392153
Node: Readline Bare Essentials393344
Node: Readline Movement Commands395155
Node: Readline Killing Commands396154
Node: Readline Arguments398180
Node: Searching399273
Node: Readline Init File401519
Node: Readline Init File Syntax402825
Node: Conditional Init Constructs429779
Node: Sample Init File434167
Node: Bindable Readline Commands437290
Node: Commands For Moving438831
Node: Commands For History441298
Node: Commands For Text447458
Node: Commands For Killing451586
Node: Numeric Arguments454377
Node: Commands For Completion455532
Node: Keyboard Macros461231
Node: Miscellaneous Commands461935
Node: Readline vi Mode469481
Node: Programmable Completion470461
Node: Programmable Completion Builtins480200
Node: A Programmable Completion Example491940
Node: Using History Interactively497288
Node: Bash History Facilities497972
Node: Bash History Builtins502641
Node: History Interaction510239
Node: Event Designators515192
Node: Word Designators516773
Node: Modifiers519168
Node: Installing Bash521108
Node: Basic Installation522227
Node: Compilers and Options526106
Node: Compiling For Multiple Architectures526859
Node: Installation Names528615
Node: Specifying the System Type530852
Node: Sharing Defaults531601
Node: Operation Controls532318
Node: Optional Features533340
Node: Reporting Bugs546066
Node: Major Differences From The Bourne Shell547426
Node: GNU Free Documentation License568856
Node: Indexes594036
Node: Builtin Index594490
Node: Reserved Word Index601591
Node: Variable Index604039
Node: Function Index621455
Node: Concept Index635883

End Tag Table
+16 -10
View File
@@ -6560,7 +6560,8 @@ message format.
@item histappend
If set, the history list is appended to the file named by the value
of the @env{HISTFILE}
variable when the shell exits, rather than overwriting the file.
variable when the shell exits, rather than
potentially overwriting the file.
@item histreedit
If set, and Readline is being used,
@@ -7407,17 +7408,22 @@ If @env{HISTFILE} is unset or null,
the shell does not save the command history when it exits.
@item HISTFILESIZE
The maximum number of lines contained in the history file.
When this variable is assigned a value, the history file is truncated,
if necessary, to contain no more than
the number of history entries
that total no more than that number of lines
The maximum number of lines or history entries contained in the history file.
When this variable is assigned a value,
the history file is truncated, if necessary,
to contain no more than
that number of history entries or lines,
depending on the value of @env{HISTTIMEFORMAT},
by removing the oldest entries.
If the history list contains multi-line entries,
the history file may contain more lines than this maximum
to avoid leaving partial history entries.
@xref{Bash History Facilities},
for a description of how
@env{HISTTIMEFORMAT}
affects how the value is treated and
whether it refers to lines or history entries.
The history file is also truncated to this size after
writing it when a shell exits or by the @code{history} builtin.
writing it when a shell exits.
If the value is 0, the history file is truncated to zero size.
Non-numeric values and numeric values less than zero inhibit truncation.
The shell sets the default value to the value of @env{HISTSIZE}
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2026 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Thu Aug 20 11:42:13 EDT 2026
@set LASTCHANGE Thu Aug 27 13:00:35 EDT 2026
@set EDITION 5.4
@set VERSION 5.4
@set UPDATED 20 August 2026
@set UPDATED 27 August 2026
@set UPDATED-MONTH August 2026
+25 -13
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2020,2022-2024 Free Software Foundation, Inc.
Copyright (C) 2020,2022-2026 Free Software Foundation, Inc.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,12 +38,14 @@ typedef struct sort_element {
static int reverse_flag;
static int numeric_flag;
static int index_flag;
static int
compare(const void *p1, const void *p2)
{
const sort_element e1 = *(sort_element *) p1;
const sort_element e2 = *(sort_element *) p2;
char *x1, *x2;
if (numeric_flag) {
if (reverse_flag)
@@ -52,10 +54,14 @@ compare(const void *p1, const void *p2)
return (e1.num > e2.num) ? 1 : (e1.num < e2.num) ? -1 : 0;
}
else {
if (reverse_flag)
return strcoll(e2.value, e1.value);
else
return strcoll(e1.value, e2.value);
if (index_flag == 2 && e1.key && e2.key) { /* associative array with -I */
x1 = e1.key;
x2 = e2.key;
} else {
x1 = e1.value;
x2 = e2.value;
}
return (reverse_flag ? strcoll(x2, x1) strcoll(x1, x2));
}
}
@@ -99,6 +105,7 @@ sort_index(SHELL_VAR *dest, SHELL_VAR *source)
i = 0;
for (ae = element_forw(array->head); ae != array->head; ae = element_forw(ae)) {
sa[i].key = NULL;
sa[i].v = ae;
if (numeric_flag)
sa[i].num = strtod(element_value(ae), NULL);
@@ -188,15 +195,15 @@ asort_builtin(WORD_LIST *list)
SHELL_VAR *var, *var2;
char *word;
int opt, ret;
int index_flag = 0;
numeric_flag = 0;
reverse_flag = 0;
numeric_flag = reverse_flag = index_flag = 0;
reset_internal_getopt();
while ((opt = internal_getopt(list, "inr")) != -1) {
while ((opt = internal_getopt(list, "inrI")) != -1) {
switch (opt) {
case 'i': index_flag = 1; break;
case 'I': index_flag = 2; break;
case 'n': numeric_flag = 1; break;
case 'r': reverse_flag = 1; break;
CASE_HELPOPT;
@@ -228,10 +235,10 @@ asort_builtin(WORD_LIST *list)
}
var2 = find_variable(list->next->word->word);
if ( !var2 || ( !array_p(var2) && !assoc_p(var2) ) ) {
builtin_error("%s: Not an array", list->next->word->word);
builtin_error("%s: not an array", list->next->word->word);
return EXECUTION_FAILURE;
}
var = builtin_find_indexed_array(list->word->word, 1);
var = builtin_find_indexed_array(list->word->word, 0);
if (var == 0)
return EXECUTION_FAILURE;
return sort_index(var, var2);
@@ -266,10 +273,15 @@ char *asort_doc[] = {
" -n compare according to string numerical value",
" -r reverse the result of comparisons",
" -i sort using indices/keys",
" -I sort associative arrays using values",
"",
"If -i is supplied, SOURCE is not sorted in-place, but the indices (or keys",
"if associative) of SOURCE, after sorting it by its values, are placed as",
"values in the indexed array DEST",
"values in the indexed array DEST.",
"",
"If -I is supplied instead, SOURCE is sorted by its keys and those keys",
"are placed, in order, as values in the indexed array DEST. This only",
"makes sense for associative arrays.",
"",
"Associative arrays may not be sorted in-place.",
"",
@@ -284,6 +296,6 @@ struct builtin asort_struct = {
asort_builtin,
BUILTIN_ENABLED,
asort_doc,
"asort [-nr] array ... or asort [-nr] -i dest source",
"asort [-nr] array ... or asort [-nr] -i|-I dest source",
0
};
+34 -7
View File
@@ -85,8 +85,26 @@ by reading history entries from the
file named by the @env{HISTFILE} variable (default @file{~/.bash_history}).
This is referred to as the @dfn{history file}.
The history file is truncated, if necessary,
to contain no more than the number of history entries
to contain no more than the number of lines or history entries
specified by the value of the @env{HISTFILESIZE} variable.
The value of @env{HISTFILESIZE}
is interpreted as lines or possibly multi-line history
entries depending on whether the @env{HISTTIMEFORMAT}
variable has a value,
since that controls whether or not timestamps are written
to the history file.
If @env{HISTTIMEFORMAT}
has a value,
@env{HISTFILESIZE}
is interpreted as a number of
history entries, including timestamps.
If it does not, @env{HISTFILESIZE}
is interpreted as a number of lines,
which may result in incomplete history entries in the history file,
or the history file containing more lines than this maximum
to avoid leaving partial history entries.
If @env{HISTFILESIZE} is unset, or set to null, a non-numeric value,
or a numeric value less than zero, the history file is not truncated.
@@ -98,17 +116,26 @@ These timestamps are optionally displayed depending on the value of the
When present, history timestamps delimit history entries, making
multi-line entries possible.
When a shell with history enabled exits, Bash copies the last
@env{$HISTSIZE} entries from the history list to the file
named by @env{$HISTFILE}.
When a shell with history enabled exits, Bash
copies up to the last
@env{$HISTSIZE}
entries from the history list
to the file named by
@env{$HISTFILE}.
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
Bash appends the entries to the history file,
otherwise it overwrites the history file.
or if the number of history entries entered
during the current shell session is less than
@env{$HISTSIZE},
Bash appends the history entries entered during the current session
to @env{$HISTFILE}.
If @code{histappend} is not set, and the number of entries from the current
shell session exceeds @env{$HISTSIZE},
it overwrites the history file with the entries from the current session.
If @env{HISTFILE} is unset or null,
or if the history file is unwritable, the history is not saved.
After saving the history, Bash truncates the history file
to contain no more than @env{$HISTFILESIZE}
lines as described above.
entries as described above.
If the @env{HISTTIMEFORMAT}
variable is set, the shell writes the timestamp information
+8
View File
@@ -613,6 +613,7 @@ history_truncate_file (const char *fname, int lines)
{
char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv, orig_lines, exists, r;
int has_timestamps;
struct stat finfo, nfinfo;
size_t file_size;
@@ -695,6 +696,11 @@ history_truncate_file (const char *fname, int lines)
}
buffer[chars_read] = '\0'; /* for the initial check of bp1[1] */
/* use a heuristic like in read_history_range() to determine whether the
file has timestamps, but don't change the comment character so
HIST_TIMESTAMP_START doesn't return true */
has_timestamps = history_comment_char == '\0' && buffer[0] == '#' && isdigit ((unsigned char)buffer[1]);
/* Count backwards from the end of buffer until we have passed
LINES lines. bp1 is set funny initially. But since bp[1] can't
be a comment character (since it's off the end) and *bp can't be
@@ -703,6 +709,8 @@ history_truncate_file (const char *fname, int lines)
because we decrement it one extra time the first time through the loop
and we need the final timestamp line. */
lines += history_write_timestamps;
if (history_write_timestamps == 0)
lines += has_timestamps; /* do our best */
for (bp1 = bp = buffer + chars_read - 1; lines > 0 && bp > buffer; bp--)
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)