1 This file is history.def, from which is created history.c.
2 It implements the builtin "history" in Bash.
4 Copyright (C) 1987-2009 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
24 $FUNCTION history_builtin
26 $SHORT_DOC history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
27 Display or manipulate the history list.
29 Display the history list with line numbers, prefixing each modified
30 entry with a `*'. An argument of N lists only the last N entries.
33 -c clear the history list by deleting all of the entries
34 -d offset delete the history entry at offset OFFSET.
36 -a append history lines from this session to the history file
37 -n read all history lines not already read from the history file
38 -r read the history file and append the contents to the history
40 -w write the current history to the history file
41 and append them to the history list
43 -p perform history expansion on each ARG and display the result
44 without storing it in the history list
45 -s append the ARGs to the history list as a single entry
47 If FILENAME is given, it is used as the history file. Otherwise,
48 if $HISTFILE has a value, that is used, else ~/.bash_history.
50 If the $HISTTIMEFORMAT variable is set and not null, its value is used
51 as a format string for strftime(3) to print the time stamp associated
52 with each displayed history entry. No time stamps are printed otherwise.
55 Returns success unless an invalid option is given or an error occurs.
61 #include "../bashtypes.h"
62 #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
63 # include <sys/file.h>
65 #include "posixstat.h"
69 #if defined (HAVE_UNISTD_H)
73 #include "../bashansi.h"
74 #include "../bashintl.h"
77 #include "../bashhist.h"
78 #include <readline/history.h>
79 #include "bashgetopt.h"
86 extern int current_command_line_count;
87 extern int force_append_history; /* shopt -s histappend */
89 static char *histtime __P((HIST_ENTRY *, const char *));
90 static int display_history __P((WORD_LIST *));
91 static void push_history __P((WORD_LIST *));
92 static int expand_and_print_history __P((WORD_LIST *));
104 history_builtin (list)
107 int flags, opt, result, old_history_lines, obase;
108 char *filename, *delete_arg;
109 intmax_t delete_offset;
112 reset_internal_getopt ();
113 while ((opt = internal_getopt (list, "acd:npsrw")) != -1)
137 delete_arg = list_optarg;
140 #if defined (BANG_HISTORY)
151 opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG);
152 if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG)
154 builtin_error (_("cannot use more than one of -anrw"));
155 return (EXECUTION_FAILURE);
158 /* clear the history, but allow other arguments to add to it again. */
161 bash_clear_history ();
163 return (EXECUTION_SUCCESS);
170 return (EXECUTION_SUCCESS);
172 #if defined (BANG_HISTORY)
173 else if (flags & PFLAG)
176 return (expand_and_print_history (list));
177 return (sh_chkwrite (EXECUTION_SUCCESS));
180 else if (flags & DFLAG)
182 if ((legal_number (delete_arg, &delete_offset) == 0)
183 || (delete_offset < history_base)
184 || (delete_offset > (history_base + history_length)))
186 sh_erange (delete_arg, _("history position"));
187 return (EXECUTION_FAILURE);
190 result = bash_delete_histent (opt - history_base);
191 /* Since remove_history changes history_length, this can happen if
192 we delete the last history entry. */
193 if (where_history () > history_length)
194 history_set_pos (history_length);
195 return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
197 else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0)
199 result = display_history (list);
200 return (sh_chkwrite (result));
203 filename = list ? list->word->word : get_string_value ("HISTFILE");
204 result = EXECUTION_SUCCESS;
206 if (flags & AFLAG) /* Append session's history to file. */
207 result = maybe_append_history (filename);
208 else if (flags & WFLAG) /* Write entire history. */
209 result = write_history (filename);
210 else if (flags & RFLAG) /* Read entire file. */
211 result = read_history (filename);
212 else if (flags & NFLAG) /* Read `new' history from file. */
214 /* Read all of the lines in the file that we haven't already read. */
215 old_history_lines = history_lines_in_file;
216 obase = history_base;
219 result = read_history_range (filename, history_lines_in_file, -1);
222 history_lines_in_file = where_history ();
224 /* If we're rewriting the history file at shell exit rather than just
225 appending the lines from this session to it, the question is whether
226 we reset history_lines_this_session to 0, losing any history entries
227 we had before we read the new entries from the history file, or
228 whether we count the new entries we just read from the file as
229 history lines added during this session.
230 Right now, we do the latter. This will cause these history entries
231 to be written to the history file along with any intermediate entries
232 we add when we do a `history -a', but the alternative is losing
234 if (force_append_history == 0)
235 history_lines_this_session += history_lines_in_file - old_history_lines +
236 history_base - obase;
239 return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
242 /* Accessors for HIST_ENTRY lists that are called HLIST. */
243 #define histline(i) (hlist[(i)]->line)
244 #define histdata(i) (hlist[(i)]->data)
247 histtime (hlist, histtimefmt)
249 const char *histtimefmt;
251 static char timestr[128];
254 t = history_get_time (hlist);
256 strftime (timestr, sizeof (timestr), histtimefmt, localtime (&t));
258 strcpy (timestr, "??");
263 display_history (list)
269 char *histtimefmt, *timestr;
273 if (get_numeric_arg (list, 0, &limit) == 0)
274 return (EXECUTION_FAILURE);
282 hlist = history_list ();
286 for (i = 0; hlist[i]; i++)
289 if (0 <= limit && limit < i)
294 histtimefmt = get_string_value ("HISTTIMEFORMAT");
300 timestr = (histtimefmt && *histtimefmt) ? histtime (hlist[i], histtimefmt) : (char *)NULL;
301 printf ("%5d%c %s%s\n", i + history_base,
302 histdata(i) ? '*' : ' ',
303 ((timestr && *timestr) ? timestr : ""),
309 return (EXECUTION_SUCCESS);
312 /* Remove the last entry in the history list and add each argument in
313 LIST to the history. */
320 /* Delete the last history entry if it was a single entry added to the
321 history list (generally the `history -s' itself), or if `history -s'
322 is being used in a compound command and the compound command was
323 added to the history as a single element (command-oriented history).
324 If you don't want history -s to remove the compound command from the
325 history, change #if 0 to #if 1 below. */
327 if (remember_on_history && hist_last_line_pushed == 0 &&
328 hist_last_line_added && bash_delete_last_history () == 0)
330 if (remember_on_history && hist_last_line_pushed == 0 &&
331 (hist_last_line_added ||
332 (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
333 && bash_delete_last_history () == 0)
337 s = string_list (list);
338 /* Call check_add_history with FORCE set to 1 to skip the check against
339 current_command_line_count. If history -s is used in a compound
340 command, the above code will delete the compound command's history
341 entry and this call will add the line to the history as a separate
342 entry. Without FORCE=1, if current_command_line_count were > 1, the
343 line would be appended to the entry before the just-deleted entry. */
344 check_add_history (s, 1); /* obeys HISTCONTROL, HISTIGNORE */
346 hist_last_line_pushed = 1; /* XXX */
350 #if defined (BANG_HISTORY)
352 expand_and_print_history (list)
358 if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
359 return EXECUTION_FAILURE;
360 result = EXECUTION_SUCCESS;
363 r = history_expand (list->word->word, &s);
366 builtin_error (_("%s: history expansion failed"), list->word->word);
367 result = EXECUTION_FAILURE;
380 #endif /* BANG_HISTORY */