bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Issues with history substitution and its documentation


From: Jim Monte
Subject: Re: Issues with history substitution and its documentation
Date: Mon, 4 Nov 2019 09:42:39 -0500

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 <address@hidden> 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 <address@hidden> 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 <address@hidden> 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: address@hidden
>>> 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 &.
>>>
>>>
>>>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]