[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Bash fc out-of-range incompatibility with POSIX and ksh
From: |
Paul Eggert |
Subject: |
Bash fc out-of-range incompatibility with POSIX and ksh |
Date: |
Mon, 19 Nov 2001 17:03:32 -0800 (PST) |
Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu'
-DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H -I. -I.. -I../include -I../lib -g
-O2
uname output: Linux dum.twinsun.com 2.2.18ss.e820-bda652a #4 SMP Tue Jun 5
11:24:08 PDT 2001 i686 unknown
Machine Type: i686-pc-linux-gnu
Bash Version: 2.05a
Patch Level: 0
Release Status: release
Description:
I ran into this problem when switching from ksh to Bash.
I used the following function:
hi() { fc -l -10; }
to get the last 10 lines of history. Bash prints an error
if I invoke "fc -l -10" and there are fewer than 10 lines of
history. ksh just prints all the lines that there are, with
no error.
I had a similar problem with this function:
wh() { fc -l 1 | grep -e "$1"; }
It works correctly with ksh, but not with Bash, once the
history base grows past 1.
POSIX 1003.2-1992 section 5.12.14 page 547 lines 2212-2219
require the ksh behavior. Here's a quote:
When a range of commands is used, it shall not be an error to
specify first or last values that are not in the history list; fc
shall substitute the value representing the oldest or newest
command in the list, as appropriate. For example, if there are only
ten commands in the history list, numbered 1 to 10:
fc -l
fc 1 99
shall list and edit, respectively, all ten commands.
Repeat-By:
$ echo foo
foo
$ fc -l 10000000
bash: fc: history specification out of range
The last line should be something like
"23 echo foo" instead.
Fix:
2001-11-19 Paul Eggert <eggert@twinsun.com>
* builtins/fc.def (fc_gethnum):
If a number is out of range, substitute the nearest
value in range. ksh does this, and POSIX requires it.
(fc_builtin): Don't bother checking for (histbeg > last_hist) ||
(histend > last_hist); it's impossible now.
===================================================================
RCS file: builtins/fc.def,v
retrieving revision 2.5.1.4.0.1
retrieving revision 2.5.1.4.0.2
diff -pu -r2.5.1.4.0.1 -r2.5.1.4.0.2
--- builtins/fc.def 2001/11/19 06:00:59 2.5.1.4.0.1
+++ builtins/fc.def 2001/11/20 00:42:15 2.5.1.4.0.2
@@ -313,8 +313,7 @@ fc_builtin (list)
}
/* We print error messages for line specifications out of range. */
- if ((histbeg < 0) || (histend < 0) ||
- (histbeg > last_hist) || (histend > last_hist))
+ if ((histbeg < 0) || (histend < 0))
{
builtin_error ("history specification out of range");
return (EXECUTION_FAILURE);
@@ -457,19 +456,20 @@ fc_gethnum (command, hlist)
n = atoi (s);
n *= sign;
- /* Anything specified greater than the last history element that we
- deal with is an error. */
- if (n > i + history_base)
- return (-1);
-
/* If the value is negative or zero, then it is an offset from
the current history item. */
if (n < 0)
- return (i + n + 1);
+ {
+ n += i + 1;
+ return (n < 0 ? 0 : n);
+ }
else if (n == 0)
return (i);
else
- return (n - history_base);
+ {
+ n -= history_base;
+ return (i < n ? i : n);
+ }
}
clen = strlen (command);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Bash fc out-of-range incompatibility with POSIX and ksh,
Paul Eggert <=