Another documentation issue for :s, and a bug, or two bugs, although it seems to be one of each. Instead of "Any delimiter may be used in place of ‘/’.", it should be clarified that any character may be used in place of '/' as a delimiter, although if '&' is used, it looses its special property of being the value of old when it appears in new and if '\' is used, it looses is ability to escape '&'. However, there is still an issue with an escape being lost in some cases.
[root@localhost ~]# echo a b c a b c [root@localhost ~]# echo "!:s&b&\\\&&&" echo "echo a \& c&" ******************* one less '\' escape echo a \& c& [root@localhost ~]# echo a b c a b c [root@localhost ~]# echo "!:s/b/\\\&&/" echo "echo a \\&b c" ******************* echo a \&b c [root@localhost ~]# echo a b c a b c [root@localhost ~]# echo "!:szbz\\\&&z" echo "echo a \\&b c" ******************* echo a \&b c [root@localhost ~]# echo a b c a b c [root@localhost ~]# echo "!:s\b\\\\&&\" echo "echo a c\\&&\" > " echo a c\&&" [root@localhost ~]# echo a b c a b c [root@localhost ~]# echo "!:s\b\z\&&y\" echo "echo a z c&&y\" > " echo a z c&&y" Jim On Wed, Nov 6, 2019 at 8:04 AM Jim Monte <jim.mont...@gmail.com> wrote: > Regarding the & word modifier, it would be useful to note in the > documentation that it applies the previous substitution whether it had been > successful or not, as shown below. > > [root@localhost ~]# echo a > a > [root@localhost ~]# !:s/a/z/ > echo z > z > [root@localhost ~]# echo a1 > a1 > [root@localhost ~]# !:& > echo z1 > z1 > [root@localhost ~]# echo a2 > a2 > [root@localhost ~]# !:s/b/y/ > bash: :s/b/y/: substitution failed > [root@localhost ~]# echo b2 > b2 > [root@localhost ~]# !:& > echo y2 > y2 > [root@localhost ~]# > > > Jim > > On Tue, Nov 5, 2019 at 11:44 AM Jim Monte <jim.mont...@gmail.com> wrote: > >> The availability of the % string only after a command unrelated to it >> (not using !??) is executed as shown below is not documented, but it >> probably falls under the category of a bug. That is, it seems reasonable >> that both echo "!%" commands should behave as the second one does. >> [root@localhost ~]# bash >> [root@localhost ~]# echo "!%" >> bash: !: event not found >> [root@localhost ~]# echo a >/dev/nul >> [root@localhost ~]# echo "!%" >> echo "" >> >> [root@localhost ~]# >> >> Jim >> >> On Mon, Nov 4, 2019 at 9:42 AM Jim Monte <jim.mont...@gmail.com> wrote: >> >>> Related to the issues with the ? event designator, the %word designator >>> substitutes the *first* word matched by the ? event designator or nothing >>> if the match begins with a space. These details are not documented. >>> >>> [root@localhost ~]# echo a b c d >/dev/nul >>> [root@localhost ~]# echo !?b c? >>> echo echo a b c d >/dev/nul >>> [root@localhost ~]# echo "!%" >>> echo "b" >>> b >>> [root@localhost ~]# echo a1 >/dev/nul >>> [root@localhost ~]# echo !? a? >>> echo echo a1 >/dev/nul >>> [root@localhost ~]# echo "!%" >>> echo "" >>> >>> Jim >>> >>> >>> >>> >>> >>> On Sun, Nov 3, 2019 at 9:18 AM Jim Monte <jim.mont...@gmail.com> wrote: >>> >>>> Two more documentation issues I have found are below. >>>> >>>> It appears that an empty substring event designator uses the string of >>>> the previous substring event designator if none is provided and does not >>>> find the event if there is no previous string. >>>> >>>> [root@localhost ~]# ls >>>> dos hello.c >>>> [root@localhost ~]# cat hello.c > /dev/nul >>>> [root@localhost ~]# echo !?s? >>>> echo ls >>>> ls >>>> [root@localhost ~]# echo !?? >>>> echo echo ls >>>> echo ls >>>> [root@localhost ~]# ls -al > /dev/nul >>>> [root@localhost ~]# echo !?? >>>> echo ls -al > /dev/nul >>>> [root@localhost ~]# echo s >>>> s >>>> [root@localhost ~]# echo !?? >>>> echo echo s >>>> echo s >>>> [root@localhost ~]# echo !?l? >>>> echo echo ls -al > /dev/nul >>>> [root@localhost ~]# echo !?? >>>> echo echo echo ls -al > /dev/nul >>>> >>>> [root@localhost ~]# bash >>>> [root@localhost ~]# echo !?? >>>> bash: !??: event not found >>>> >>>> This action is not documented. >>>> >>>> >>>> >>>> >>>> >>>> An empty "old" string in a substitute word modifier uses the previous >>>> "old" if none is given, but uses an empty string if new is empty. If there >>>> was no previous "old" string, an error is reported. >>>> >>>> [root@localhost ~]# echo f g i >>>> f g i >>>> [root@localhost ~]# echo !:s/g/k/ >>>> echo echo f k i >>>> echo f k i >>>> [root@localhost ~]# echo af ag ai >>>> af ag ai >>>> [root@localhost ~]# echo !:s/// >>>> echo echo af a ai >>>> echo af a ai >>>> [root@localhost ~]# echo bf bg bi >>>> bf bg bi >>>> [root@localhost ~]# echo !:s//1/ >>>> echo echo bf b1 bi >>>> echo bf b1 bi >>>> [root@localhost ~]# echo gf gg gi >>>> gf gg gi >>>> [root@localhost ~]# echo !:gs//2/ >>>> echo echo 2f 22 2i >>>> echo 2f 22 2i >>>> >>>> [root@localhost ~]# bash >>>> [root@localhost ~]# echo a b c >>>> a b c >>>> [root@localhost ~]# echo !:s//1/ >>>> bash: :s//1/: no previous substitution >>>> >>>> Again, this behavior is not documented. >>>> >>>> On Thu, Oct 10, 2019 at 10:35 PM Jim Monte <jim.mont...@gmail.com> >>>> wrote: >>>> >>>>> Hi, >>>>> >>>>> This bug report has been my first one for Bash. I have not found how >>>>> to check the status of the bug. Would you please provide this information? >>>>> >>>>> Below are a couple more issues I found. >>>>> >>>>> There is an inconsistency with the documentation and behavior of the ^ >>>>> word designator. According to documentation, it refers to the first >>>>> argument but does not require a ':' before it if it starts the word >>>>> designator. However, it does not act like the numerical word designator 1 >>>>> at the end of a range. >>>>> >>>>> [root@localhost ~]# echo a b c >>>>> a b c >>>>> [root@localhost ~]# echo !!:1-1 >>>>> echo a >>>>> a >>>>> [root@localhost ~]# echo a b c >>>>> a b c >>>>> [root@localhost ~]# echo !!:^-^ >>>>> echo a b^ >>>>> a b^ >>>>> >>>>> Also it is not explicitly documented that :- is equivalent to :0- >>>>> >>>>> [root@localhost ~]# echo a b c d >>>>> a b c d >>>>> [root@localhost ~]# echo !!:- >>>>> echo echo a b c >>>>> echo a b c >>>>> [root@localhost ~]# echo a b c d >>>>> a b c d >>>>> [root@localhost ~]# echo !!:0- >>>>> echo echo a b c >>>>> echo a b c >>>>> >>>>> >>>>> Jim Monte >>>>> >>>>> On Thu, Oct 3, 2019 at 6:19 PM Jim Monte <jim.mont...@gmail.com> >>>>> wrote: >>>>> >>>>>> Hi All, >>>>>> >>>>>> Below are some issues I found with history substitution. I am >>>>>> duplicating its behavior in a somewhat different use, and found issues >>>>>> with >>>>>> the documentation and bugs as described. >>>>>> >>>>>> Jim Monte >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> From: jim >>>>>> To: bug-bash@gnu.org >>>>>> Subject: Issues with history substitution and its documentation >>>>>> >>>>>> Configuration Information [Automatically generated, do not change]: >>>>>> Machine: x86_64 >>>>>> OS: linux-gnu >>>>>> Compiler: gcc >>>>>> Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' >>>>>> -DCONF_OSTYPE='l$ >>>>>> uname output: Linux T5500-Ubuntu 4.18.0-22-generic #23~18.04.1-Ubuntu >>>>>> SMP Thu J$ >>>>>> Machine Type: x86_64-pc-linux-gnu >>>>>> >>>>>> Bash Version: 4.4 >>>>>> Patch Level: 19 >>>>>> Release Status: release >>>>>> >>>>>> Description: >>>>>> >>>>>> ============================================================================= >>>>>> Documentation of quick substitution is incorrect (or does not match >>>>>> behavior). >>>>>> >>>>>> I believe this issue is an error with the documentation of history >>>>>> "Quick Substitution" that has existed since the first snapshot >>>>>> available at >>>>>> web.archive.org in 2007 at >>>>>> >>>>>> >>>>>> https://web.archive.org/web/20071223174140/http://www.gnu.org/software/bash/manual/html_node/Event-Designators.html >>>>>> >>>>>> At the least it is true that bash does not behave as the >>>>>> documentation states, >>>>>> but it does act in a way that is more reasonable (to me) than what is >>>>>> written. >>>>>> >>>>>> The documentation states that ^string1^string2^ is equivalent to >>>>>> !!:s/string1/string2/. However, bash treats it as equivalent to >>>>>> !!:s^string1^string2^. >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo /a >>>>>> /a >>>>>> jim@T5500-Ubuntu:~$ ^/a^b^ >>>>>> echo b >>>>>> b >>>>>> jim@T5500-Ubuntu:~$ echo /a >>>>>> /a >>>>>> jim@T5500-Ubuntu:~$ !!:s//a/b/ >>>>>> echo ab/ >>>>>> ab/ >>>>>> jim@T5500-Ubuntu:~$ echo /a >>>>>> /a >>>>>> jim@T5500-Ubuntu:~$ !!:s^/a^b^ >>>>>> echo b >>>>>> b >>>>>> >>>>>> >>>>>> ============================================================================= >>>>>> Behavior of empty "old" string in a substitution is undefined. >>>>>> >>>>>> The earlier example also shows a related but different issue with the >>>>>> !!:s//a/b/ command, where the string to locate is empty. >>>>>> It causes /a to be replaced by a and the b/ is appended. >>>>>> >>>>>> But >>>>>> jim@T5500-Ubuntu:~$ echo ///a >>>>>> ///a >>>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>>> echo //z >>>>>> //z >>>>>> >>>>>> Here the empty string caused /a to be replaced by z. >>>>>> >>>>>> However, >>>>>> jim@T5500-Ubuntu:~$ echo ///abcdefg >>>>>> ///abcdefg >>>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>>> echo //zbcdefg >>>>>> //zbcdefg >>>>>> >>>>>> Here a slash and the first character of the second word are replaced >>>>>> by z. >>>>>> >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>>> echo z b c >>>>>> z b c >>>>>> >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo /// >>>>>> /// >>>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>>> bash: :s//z/: substitution failed >>>>>> >>>>>> Using :gs instead of :s does not change the results. >>>>>> >>>>>> >>>>>> ============================================================================= >>>>>> BUG >>>>>> If an event designator has a leading - character, it is ignored. >>>>>> >>>>>> jim@T5500-Ubuntu:~/tmp$ cat main.c >>>>>> #include <stdio.h> >>>>>> int main(void) >>>>>> { >>>>>> (void) fprintf(stdout, "Hello, world!\n"); >>>>>> return 0; >>>>>> } >>>>>> >>>>>> jim@T5500-Ubuntu:~/tmp$ gcc main.c -o"-a" >>>>>> jim@T5500-Ubuntu:~/tmp$ gcc main.c -o"-b" >>>>>> jim@T5500-Ubuntu:~/tmp$ -a >>>>>> Hello, world! >>>>>> jim@T5500-Ubuntu:~/tmp$ !-a:s/a/b >>>>>> bpt-cache abc >>>>>> >>>>>> >>>>>> >>>>>> ============================================================================= >>>>>> Documentation of the :h and :t modifiers in section 9.3.3 is >>>>>> incomplete. >>>>>> :h removes the last / and everything after it if a / is present. >>>>>> Otherwise >>>>>> it does nothing. >>>>>> >>>>>> :t removes everything before and including the last / if one is >>>>>> present. >>>>>> Otherwise it does nothing. >>>>>> >>>>>> If a slash is present, !!:h/!!:t is equivalent to !!. >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>>> /a/b/c/d >>>>>> jim@T5500-Ubuntu:~$ !!:h >>>>>> echo /a/b/c >>>>>> /a/b/c >>>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>>> /a/b/c/d >>>>>> jim@T5500-Ubuntu:~$ !!:h:h >>>>>> echo /a/b >>>>>> /a/b >>>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>>> /a/b/c/d >>>>>> jim@T5500-Ubuntu:~$ !!:h:h:h >>>>>> echo /a >>>>>> /a >>>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>>> /a/b/c/d >>>>>> jim@T5500-Ubuntu:~$ !!:h:h:h:h >>>>>> echo >>>>>> >>>>>> jim@T5500-Ubuntu:~$ >>>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>>> /a/b/c/d >>>>>> jim@T5500-Ubuntu:~$ !!:t >>>>>> d >>>>>> d: command not found >>>>>> >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo a/b >>>>>> a/b >>>>>> jim@T5500-Ubuntu:~$ !!:h/!!:t >>>>>> echo a/b >>>>>> a/b >>>>>> jim@T5500-Ubuntu:~$ echo a/b >>>>>> a/b >>>>>> jim@T5500-Ubuntu:~$ !! >>>>>> echo a/b >>>>>> a/b >>>>>> >>>>>> >>>>>> >>>>>> ============================================================================= >>>>>> Documentation of the :r and :e modifiers is incomplete. >>>>>> :r removes the last ".suffix" and everything after it, if a ".suffix" >>>>>> is >>>>>> present. Otherwise it does nothing. >>>>>> :e leaves the last ".suffix" and everything after it, if a ".suffix" >>>>>> is >>>>>> present. Otherwise it does nothing. >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo .suffix a b .suffix c d >>>>>> .suffix a b .suffix c d >>>>>> jim@T5500-Ubuntu:~$ !!:r >>>>>> echo .suffix a b >>>>>> .suffix a b >>>>>> jim@T5500-Ubuntu:~$ echo .suffix a b .suffix c d >>>>>> .suffix a b .suffix c d >>>>>> jim@T5500-Ubuntu:~$ !!:r:r >>>>>> echo >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo .suffix a b .suffix c d >>>>>> .suffix a b .suffix c d >>>>>> jim@T5500-Ubuntu:~$ !!:e >>>>>> .suffix c d >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:r >>>>>> echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:e >>>>>> echo a b c >>>>>> a b c >>>>>> >>>>>> >>>>>> ============================================================================= >>>>>> BUG >>>>>> :p does not suppress execution if it is duplicated. >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:p >>>>>> echo a b c >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:p:p >>>>>> echo a b c >>>>>> a b c >>>>>> >>>>>> >>>>>> ============================================================================= >>>>>> Documentation of :q and :x is incomplete. >>>>>> If :q and :x are repeated, the last specification is taken. >>>>>> >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:q >>>>>> 'echo a b c' >>>>>> echo a b c: command not found >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:x >>>>>> 'echo' 'a' 'b' 'c' >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:q:x >>>>>> 'echo' 'a' 'b' 'c' >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:q:x:q >>>>>> 'echo a b c' >>>>>> echo a b c: command not found >>>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>>> a b c >>>>>> jim@T5500-Ubuntu:~$ !!:q:x:q:x >>>>>> 'echo' 'a' 'b' 'c' >>>>>> a b c >>>>>> >>>>>> >>>>>> >>>>>> ============================================================================= >>>>>> Finally, documentation of G should mention that it can be used with >>>>>> both :s and &. >>>>>> >>>>>> >>>>>>