gnb@melba.bby.oz.au (Gregory Bond) (09/14/89)
1) If you have a path line like PATH=:/bin:/usr/bin:~/bin:/usr/local/bin then when it is exported, the ~ is not expanded. This confuses subsequent invocations of /bin/sh or other programs that parse paths, for example make. Csh does expand components of the path it exports. 2) the present simple-minded history substitution has some surprises for csh users. I have noted in the past the lack of delimiter escaping or :gs global substitutions or "&" pattern replacement. This one annoys me a lot: you can't add slashes with ^.^./^ as this is treated as "!!:s/././/" which does nothing at all. Nor does ^x^xx^lly (or the equivalent ":s/x/xx/lly") do what is expected (i.e. turn txt into txxtlly). Some serious rewrite of the history editing code would need to be done to make bash csh-compatible in this area. Is this a desired end, or is there some other model of history editing bash is trying to emulate? I have started looking at these problems and may eventually produce a better history editor. Greg. BTW: I have patches to add FIGNORE to the 1.03 filename completion (a la SunOS csh set fignore ()) if anyone is interested.
bfox@AUREL.CALTECH.EDU (Brian Fox) (09/15/89)
Date: Thu, 14 Sep 89 19:05:36 +1000 From: Gregory Bond <munnari!melba.bby.oz.au!gnb@uunet.uu.net> 1) If you have a path line like PATH=:/bin:/usr/bin:~/bin:/usr/local/bin then when it is exported, the ~ is not expanded. This confuses subsequent invocations of /bin/sh or other programs that parse paths, for example make. Csh does expand components of the path it exports. Csh expands words beginning with whitespace. It does not have to expand the components of PATH, which are separated by colons. I could special case the PATH variable, which I think is ugly beyond belief. This one annoys me a lot: you can't add slashes with ^.^./^ as Yes, you can. Please try again. Also, please specify the version of Bash (or better yet, readline) which is giving you the problem. In that way, people won't assume that the bug exists in all versions of Bash, but perhaps only in the version that you have, or only on the hardware that you have Bash compiled on. is treated as "!!:s/././/" No, it is treated as "!!:s^.^./" ^x^xx^lly (or the equivalent ":s/x/xx/lly") doesn't do turn txt into txxtlly. This is a bug. However, I found that "!!:s/foo/bar/more text" changed "hellofooness" into "hellobarnessmore text", which is what I believe it is supposed to do. So perhaps the problem only exists in quick substitution, with the `^' character. (5 minutes pass) Okay, I fixed it. Patches for :g and for the substitution fix follow. These patches apply to bash 1.03's history.c file. Some serious rewrite of the history editing code would need to be done to make bash csh-compatible in this area. Actually, I am of the opinion that a serious rewrite of Csh would be required to give it the line editing features of Bash. In the course of writing this letter I have added "!:gs/foo/bar", so I would not suppose that a "serious" rewrite is neccessary. Is this a desired end, or is there some other model of history editing bash is trying to emulate? I provided Csh style history substitution as a bonus, and as a quick hack. I thought that people who had been used to using Csh would appreciate a little flavor of home, even though all of the history functions could be performed interactively, with the readline editing features. I had hoped that any time I spent working on the command line interface would be to enhance readline, so that features missing from my quick history hack could be better performed in the Emacs idiom. I do not expect to spend any substantial amount of time hacking on the arcane and non-intuitive Csh !-style history interface. I have already spent too much time as it is. I have started looking at these problems and may eventually produce a better history editor. If you produce a better history editor, which is clean, and provides the same interface as mine, I will be more than happy to make it a part of the Readline library. Perhaps next time, you can spend the half hour adding the features that you want instead of me! Brian Fox
bfox@AUREL.CALTECH.EDU (Brian Fox) (09/15/89)
Whoops, I forgot the patches... ---------------------------------------- File: /usr/gnu/src/lib/readline/history-diffs ---------------------------------------- *** history.c.~10~ Thu Aug 31 14:10:07 1989 --- history.c Fri Sep 15 08:53:04 1989 *************** *** 661,667 **** int i, word_spec_error = 0; int cc, modified = 0; char *word_spec, *event; ! int starting_index, only_printing = 0; char *get_history_word_specifier (), *rindex (); --- 661,667 ---- int i, word_spec_error = 0; int cc, modified = 0; char *word_spec, *event; ! int starting_index, only_printing = 0, substitute_globally = 0; char *get_history_word_specifier (), *rindex (); *************** *** 696,701 **** --- 696,702 ---- history_expansion_char, history_expansion_char, string); string = format_string; + l += 4; goto grovel; } *************** *** 853,866 **** goto next_special; /* :s/this/that substitutes `this' for `that'. */ case 's': { char *this, *that, *new_event; ! int delimiter = string[i + 2]; int si, l_this, l_that, l_temp = strlen (temp); ! if (!delimiter) break; i += 3; /* Get THIS. */ --- 854,882 ---- goto next_special; /* :s/this/that substitutes `this' for `that'. */ + /* :gs/this/that substitutes `this' for `that' globally. */ + case 'g': + if (string[i + 2] == 's') + { + i++; + substitute_globally = 1; + goto substitute; + } + else + case 's': + substitute: { char *this, *that, *new_event; ! int delimiter = 0; int si, l_this, l_that, l_temp = strlen (temp); ! if (i + 2 < strlen (string)) ! delimiter = string[i + 2]; + if (!delimiter) + break; + i += 3; /* Get THIS. */ *************** *** 889,912 **** goto cant_substitute; /* Find the first occurrence of THIS in TEMP. */ ! for (si = 0; (si + l_this) <= l_temp; si++) ! if (strncmp (temp + si, this, l_this) == 0) { ! new_event = ! (char *)alloca (1 + (l_that - l_this) + l_temp); ! strncpy (new_event, temp, si); ! strncpy (new_event + si, that, l_that); ! strncpy (new_event + si + l_that, ! temp + si + l_this, ! l_temp - (si + l_this)); ! new_event[(l_that - l_this) + l_temp] = '\0'; ! temp = new_event; goto hack_specials; } - cant_substitute: goto event_not_found; } - /* :# is the line so far. Note that we have to alloca () it since RESULT could be realloc ()'ed --- 905,945 ---- goto cant_substitute; /* Find the first occurrence of THIS in TEMP. */ ! si = 0; ! for (; (si + l_this) <= l_temp; si++) ! if (strncmp (temp + si, this, l_this) == 0) ! { ! new_event = ! (char *)alloca (1 + (l_that - l_this) + l_temp); ! strncpy (new_event, temp, si); ! strncpy (new_event + si, that, l_that); ! strncpy (new_event + si + l_that, ! temp + si + l_this, ! l_temp - (si + l_this)); ! new_event[(l_that - l_this) + l_temp] = '\0'; ! temp = new_event; ! ! if (substitute_globally) ! { ! si += l_that; ! l_temp = strlen (temp); ! substitute_globally++; ! continue; ! } ! ! goto hack_specials; ! } ! ! cant_substitute: ! ! if (substitute_globally > 1) ! { ! substitute_globally = 0; goto hack_specials; } goto event_not_found; } /* :# is the line so far. Note that we have to alloca () it since RESULT could be realloc ()'ed ----------------------------------------
gnb@melba.bby.oz.au (Gregory Bond) (09/19/89)
>From: bfox%aurel.caltech.edu@murtoa.cs.mu.oz (Brian Fox) >Subject: Bash-1.03 and exported PATH and history substitutions >Date: Fri, 15 Sep 89 09:07:19 H Date: Thu, 14 Sep 89 19:05:36 +1000 From: Gregory Bond <munnari!melba.bby.oz.au!gnb@uunet.uu.net> 1) If you have a path line like PATH=:/bin:/usr/bin:~/bin:/usr/local/bin then when it is exported, the ~ is not expanded. This confuses subsequent invocations of /bin/sh or other programs that parse paths, for example make. Csh does expand components of the path it exports. Csh expands words beginning with whitespace. It does not have to expand the components of PATH, which are separated by colons. I could special case the PATH variable, which I think is ugly beyond belief. I agree, it's ugly. However, some method of expanding ~name in PATH-like variables would be nice. I think a general-purpose mechanism is required (for things like MANPATH etc), but I can't think of any clean way to do this expansion using expr or test etc, nor can I think of a method of constructing the PATH to expand at construction time. But some special operator is also ugly. Perhaps a string-concatenation operator: PATH=:/bin:/usr/bin: + ~/bin + :rest:of:path (In csh this happens because PATH is set using the csh space-separated syntax.) This one annoys me a lot: you can't add slashes with ^.^./^ as Yes, you can. Please try again. Also, please specify the version of Bash (or better yet, readline) which is giving you the problem. Um, red faces time. I checked this before posting, but must have checked on the 1.02 shell (where it definitly didn't work). I do not expect to spend any substantial amount of time hacking on the arcane and non-intuitive Csh !-style history interface. I have already spent too much time as it is. I have started looking at these problems and may eventually produce a better history editor. If you produce a better history editor, which is clean, and provides the same interface as mine, I will be more than happy to make it a part of the Readline library. Perhaps next time, you can spend the half hour adding the features that you want instead of me! Better in the sense of more like csh - for many years of habit die hard. (The number of times I type <ESC> in bash and emacs to get file completion... ). Given the :gs stuff, the next thing I miss is & in the replacement string. I AM working on this, but it's a bit more than 1/2 hour for someone who doesn't know the code. This whole history mechanism is nasty twisted job, full of odd surprises and dark corners. I can well understand the desire to leave it behind. But, boy, I do love this shell. Greg. Bash fanatic.