Path: csiph.com!goblin3!goblin.stu.neva.ru!panix!usenet.stanford.edu!not-for-mail From: Jim Monte Newsgroups: gnu.bash.bug Subject: Re: Issues with history substitution and its documentation Date: Wed, 6 Nov 2019 08:04:12 -0500 Lines: 460 Approved: bug-bash@gnu.org Message-ID: References: NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" X-Trace: usenet.stanford.edu 1573045475 14882 209.51.188.17 (6 Nov 2019 13:04:35 GMT) X-Complaints-To: action@cs.stanford.edu To: bug-bash@gnu.org Envelope-to: bug-bash@gnu.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=JkfqO+qFD4WyL5Q5ZGUnWeI4gEuB9PgNFWUBvfC7VDM=; b=c1VaHLdhRMhMpt+GwjyZ3eBPrq9To0wAo06DtT+049zrGtI/wLGvtyRQmU1ZtQexKU qN2A/6EEr7MHLnUhGiZvIK6Hr40V72sB5B3SdEmchLbPzBhje9XFUK4tqQJNu542lsHQ znk55ZiNc5ZCJgybhwyQ+DV+JgW+Ur7MxUMfgxoK3l0rDXxhQxmWUyXSo2/0rWsHHl0P VDMrScs2VJBH15d+wMZ1xmakrxBi9J9Pfi0zeOcBsRm3GrCJq5PYekg4TfGuuy90NAlu easaqu13q/5w40J3bsCETHOzpSvuFgcuqWa9alxwZnWyt6n/s+aJAI+Cai/N+FESnSvf fvFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=JkfqO+qFD4WyL5Q5ZGUnWeI4gEuB9PgNFWUBvfC7VDM=; b=WYpgL0tqu3jYrLxH8/7rdooKWLMn6UkgUIaUQMrCGlFMfqYkjAYtp8iq4PhjwjgnuM F+JjYRwMyjiZgey8gue91I5Gj+vMmI9r33TikcNo9izN/0Xjr/W8GsJImRqy/lZFtG4x rPXUBvAJjmbpFWVcgolohACPxlhN2FRTo1bnTi03JGZP9YpxJOTebXAKKN88ZmEm+32h DbsftWl4mQSU6EVRfMGnSGtD5xshduL3UT0UXi4aYM3aUdn2Imb5CzqYhxVjQ+EQRr9r 4IuBrjWRKZapTeXs4b5teNkgZFHa6F2vu/wKfVjNptaPbrR6PqzxsY+3yHgT0cQR4vbL 7hXA== X-Gm-Message-State: APjAAAXVuh4z89dO5zzY5V7j7PlXqce4UvNHY9MoDoZzOgQw04XzfOhM THkjGVZfE/24Hfsft/VtnIMK8InoHNB4/jSspO/rQogg X-Google-Smtp-Source: APXvYqxTP+c5aFdgim4RJiDsfvgBzCQ+kundP+1uut6KzihttOvNzz1vkl+vItLI2w8vFC0o7qXLH3Msn3LqE63kj9Q= X-Received: by 2002:a92:7945:: with SMTP id u66mr2328451ilc.215.1573045464823; Wed, 06 Nov 2019 05:04:24 -0800 (PST) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::133 X-Content-Filtered-By: Mailman/MimeDel 2.1.23 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: X-Mailman-Original-References: Xref: csiph.com gnu.bash.bug:15569 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 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 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 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 >>> 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 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 >>>>> 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 &. >>>>> >>>>> >>>>>