Next word of alias to alias that end with is not checked for alias
Dear dir or madam, For the following script: alias a1='echo ' alias a2=a1 alias foo=bar a2 foo bash outputs ‘foo’, instead of ‘bar’. GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu) on archlinux as windows subsystem for linux Thanks.
Re: errexit is not suspended in a pipeline
On 1/11/23 11:22 PM, Quinn Grier wrote: I see. I had mistakenly thought that Bash's set -e description was definitively listing the contexts in which set -e is ignored, not just contexts in which set -e may not have the intended effect. It lists the scenarios where the shell will not exit. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: Next word of alias to alias that end with is not checked for alias
On 1/11/23 10:43 PM, anonymous4feedb...@outlook.com wrote: Dear dir or madam, For the following script: alias a1='echo ' alias a2=a1 alias foo=bar a2 foo bash outputs ‘foo’, instead of ‘bar’. Bash has never extended the `expand next word' semantics to multiple-level alias expansion like this, and no one has missed it. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: Next word of alias to alias that end with is not checked for alias
On Thu, Jan 12, 2023 at 03:43:15AM +, anonymous4feedb...@outlook.com wrote: > Dear dir or madam, > > For the following script: > alias a1='echo ' > alias a2=a1 > alias foo=bar > a2 foo > bash outputs ‘foo’, instead of ‘bar’. > > GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu) on archlinux as > windows subsystem for linux First thing first: aliases are not used in scripts, unless bash is invoked in POSIX mode, or the "expand_aliases" shopt is enabled. So either this wasn't really a script (i.e. you ran these commands at an interactive shell), or else this wasn't the *entire* script. Second thing: the command in question here is "a2 foo", where a2 is an alias. But the a2 alias doesn't end with a space. So there's no reason to expect that the special "alias ends with a space" processing would occur here. If you used "a1 foo" then it *would* occur. You're expecting an alias that aliases an alias to inherit the special hacks of the alias that it's aliasing. It doesn't. If you want a2 to have the space-hack behavior, put a space after it. Here's a working version: unicorn:~$ cat foo #!/bin/bash shopt -s expand_aliases alias a1='echo ' alias a2='a1 ' alias foo=bar a1 foo one a2 foo two unicorn:~$ ./foo bar one bar two In my opinion, the only bug here is in your script, not in bash. Also my opinion: aliases are disabled in bash scripts for a reason. They're ugly and horrible, and they don't promote good programming practices. Whatever you're trying to do here, I doubt aliases are the best way to do it. Consider using functions instead.
Re: Next word of alias to alias that end with is not checked for alias
Date:Thu, 12 Jan 2023 10:56:33 -0500 From:Chet Ramey Message-ID: <0f03dd45-3e1a-54b1-f884-d3fb2c1c7...@case.edu> | Bash has never extended the `expand next word' semantics to multiple-level | alias expansion like this, and no one has missed it. Bash is unique amongst shells in this - all other shells, including all ksh variants (though I don't have ksh88 to test) do produce "bar" from that test case. Unless there's some particular reason to keep it like this, this is something that perhaps should change (and really should for posix conformance in posix mode). There's nothing in posix about the "space at the end" being only applicable to the first alias located - every alias expansion should apply that. Of course, all mention of aliases should really be removed from POSIX - aliases are even worse than "set -e". kre
Re: Next word of alias to alias that end with is not checked for alias
On Fri, Jan 13, 2023 at 01:59:55AM +0700, Robert Elz wrote: > Date:Thu, 12 Jan 2023 10:56:33 -0500 > From:Chet Ramey > Message-ID: <0f03dd45-3e1a-54b1-f884-d3fb2c1c7...@case.edu> > > | Bash has never extended the `expand next word' semantics to multiple-level > | alias expansion like this, and no one has missed it. > > Bash is unique amongst shells in this - all other shells, including all > ksh variants (though I don't have ksh88 to test) do produce "bar" from > that test case. The ksh88 installed as /usr/bin/ksh on HP-UX 10.20 prints "bar".
SIGINT handling during async functions
Hi, we found quite some inconsistency and weirdness in the handling of SIGINT's during async function calls and were wondering, whether those are expected. All calls were executed from a script with jobcontrol turned off (set +m) while pressing Ctrl+C shortly afterwards. In summary: The main INT handler is never executed in foofunc (is that expected?) while the new (default) handler either aborts command execution in case of 'foofunc &' or continues execution in case of '{ foofunc; } &'. While on 'foofunc &' 'trap -p' at the beginning of foofunc (wrongly) prints the main handler, in case of '{ foofunc; } &' it suddenly prints the ignore handler "trap -- '' SIGINT" and remains indeed uninterruptible. Thus printing the trap apparently changes bash's behavior. Tested bash versions: GNU bash, Version 5.1.4(1)-release (x86_64-pc-linux-gnu) GNU bash, Version 5.2.2(1)-release (x86_64-pc-linux-gnu) on Debian Bullseye. Thanks and kind regards Tycho t='echo INT ${FUNCNAME[0]-main} >&2' trap "$t" INT foofunc(){ sleep 3; echo foo >&2; } foofunc & sleep 5 --> INT main # foofunc INT-handler is reset to default ('foo' is not printed). # Note that 'trap -p' within foofunc wrongly prints above INT handler. t='echo INT ${FUNCNAME[0]-main} >&2' trap "$t" INT foofunc(){ trap "$t" INT; sleep 3; echo foo >&2; } foofunc & sleep 5 --> INT main INT foofunc foo # foofunc custom INT-handler works. t='echo INT ${FUNCNAME[0]-main} >&2' trap "$t" INT foofunc(){ sleep 3; echo foo >&2; } { foofunc; } & sleep 5 --> INT main foo # Opposing to 'foofunc &' foo _is_ printed so apparently we have a # different default trap handler here. t='echo INT ${FUNCNAME[0]-main} >&2' trap "$t" INT foofunc(){ trap -p; sleep 3; echo foo >&2; } { foofunc; } & sleep 5 --> trap -- '' SIGINT ^CINT main $ foo # Here, when the trap is printed, INT is reported as "ignored" and foofunc # becomes indeed uninterruptible. So, 'trap -p' changes bash's behavior.
Re: SIGINT handling during async functions
Date:Fri, 13 Jan 2023 00:34:02 +0100 From:Tycho Kirchner Message-ID: <7d59c17d-792e-0ac7-fd86-b3b2e7d4b...@mail.de> | we found quite some inconsistency and weirdness | in the handling of SIGINT's during async function calls Not inconsistent or weird, and has nothing to do with function calls. | and were wondering, whether those are expected. Expected and required. | The main INT handler is never executed in foofunc [...] | Thus printing the trap apparently changes bash's behavior. Nonsense (the conclusion). When an async command (any command, not just functions, or blocks enclosed in { } ) is run with job control disabled, SIGINT is ignored for that async command. (SIGQUIT too). That has been the way shells work since before either the Bourne shell (and all later shells based upon it, like bash) or job control, were invented. That is all you are seeing here. kre
Re: SIGINT handling during async functions
Oh, the differences in what trap -p is printing is because of special case handling for trap in a subshell environment, when the trap command is the first (maybe only) command executed (details vary between shells). That is mostly intended to allow T=$(trap -p) to work, but is usually applied to any subsell environment (it is simpler that way). An async command is a subshell environment. When you do foofunc& the trap command thus prints the trap from the parent's environment, but when you embed that ina group, the traps get reset to those for the subshell before the trap command gets to run, so you see that instead. Everything is working as intended. kre
Re: SIGINT handling during async functions
Am 13.01.23 um 03:02 schrieb Robert Elz: Date:Fri, 13 Jan 2023 00:34:02 +0100 From:Tycho Kirchner Message-ID: <7d59c17d-792e-0ac7-fd86-b3b2e7d4b...@mail.de> | we found quite some inconsistency and weirdness | in the handling of SIGINT's during async function calls Not inconsistent or weird, and has nothing to do with function calls. | and were wondering, whether those are expected. Expected and required. | The main INT handler is never executed in foofunc [...] | Thus printing the trap apparently changes bash's behavior. Nonsense (the conclusion)> When an async command (any command, not just functions, or blocks enclosed in { } ) is run with job control disabled, SIGINT is ignored for that async command. (SIGQUIT too). That has been the way shells work since before either the Bourne shell (and all later shells based upon it, like bash) or job control, were invented. That is all you are seeing here. kre Dear Robert Elz, thanks for the quick response. However, did you actually actually put the short snippets into a script, executed it and verified that their behavior is the same? In particular, did you check, whether the respective 'sleep' commands kept running, after hitting Ctrl+C? On my test system, the 'sleep 3' within foofounc **is** killed in the first three code snippets, proving your statements wrong. **Only** in case of the 4th snippet, where the trap is printed at the beginning of foofunc, the 'sleep 3' command keeps running after hitting Ctrl+C. Let me give another example. Put the following commands into a script test.sh and execute it. __ bash -c 'echo first; trap -p' & wait { bash -c 'echo second; trap -p'; } & wait { trap -p >/dev/null; bash -c 'echo third; trap -p'; } & wait __ $ ./test.sh first trap -- '' SIGINT trap -- '' SIGQUIT second third trap -- '' SIGINT __ So, even in this simple case, differences are observable. Kind regards Tycho