Path: csiph.com!xmission!news.snarked.org!news.linkpendium.com!news.linkpendium.com!panix!usenet.stanford.edu!not-for-mail From: Jim Monte Newsgroups: gnu.bash.bug Subject: Re: Issues with history substitution and its documentation Date: Mon, 4 Nov 2019 09:42:39 -0500 Lines: 409 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 1572878581 25192 209.51.188.17 (4 Nov 2019 14:43:01 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=l2Hc4hpjSCjYkGVmSRFW86mukq3enpZwK6u0hyf6x1g=; b=sdTUx9kAlcB4PtDY2uuIlQe6gZmCudQIRn6Gyy4qS05GH8pHBXxv7kndwxDtoS3LYV Cf201y5c6iZwFmUaY4ZQ0FNB481Kl5gxmn/JvMFm+oeBB8huUkmVUS4SRdUgfdheW89y zM5ue4j4oDvSXJLqewoRjzHWN/5/YDfVE1eJhhRBhya80I4BLxdfZ8fOa35gK58ByPx4 3hF0aAXv/sTJrC9MGmQiCfZE+yoYgsGfp2H6Ddoi9iUsESqrO9Pjp8HXueJPSYArt6rK PyBU3B9IIqS7NUvmnQtXjJbPWGN9YssZV4D0IugiXpuKSM5KHmJ7uY8lel396/WMWF3a 44zQ== 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=l2Hc4hpjSCjYkGVmSRFW86mukq3enpZwK6u0hyf6x1g=; b=nOnofcLslLrUi+E1rUV68rszK4iCJod7mrR5/lB+LkIAqHOBLzcw6H1eOmYAGYL8Fa DAfWW3H2so6+82Itnc25qeDytjYIxaJLpCx995y4kiqS2s+X5S3p/z32XOoogBbcSGGc vjbKjfJqbk6HhNhdIdeO2t+OwlT86is1DSG+iHJAL88SexAb8ihMkKBtFb1jX8fhlfMR vkAAm6d1a0KsHgI0R4o7oUhO9UwhjDAbchLIM6Ib+g0K/e1z2OB9L7cwZq5z26CcnMNx Jvuk23+2DXComLHV9MNQ75822uySIimn5eqSNyhlaPOC4K2vPCHYDXcYzwcihb1s3utd AobA== X-Gm-Message-State: APjAAAW1yneNgOViO2BFnW9owdMIZfbxYKgv8bPQzV9PL5GgAmMs5m9w loUB3Heasdma+0ng2orLck23Q3lQV5OOtSHPRIGt9eNn X-Google-Smtp-Source: APXvYqza+EhtXCODzrbShJDCmzBUyPu/tone0Pr5F5Snq4syqWXp80ZzmeetNaDisnRhV+aty0BRs6nvoRMMpf4aFi0= X-Received: by 2002:a5d:970c:: with SMTP id h12mr254979iol.20.1572878571381; Mon, 04 Nov 2019 06:42:51 -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::d2c 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:15565 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 &. >>> >>> >>>