Re: Assign Default Value expansion inserts ASCII DEL for empty 'word'
On 3/9/20 3:29 PM, Martin Castillo wrote: > Bash Version: 5.0 > Patch Level: 16 > Release Status: release > > Description: > Out of nowhere, bash inserts an ascii DEL in the first expansion. That > is very unexpected and shouldn't be there. Thanks for the report. This happens in the case where the expansion assigns a quoted null string and there is something else (non-null) in the expanded string. I'll fix it in the next devel branch push. Chet -- ``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/
command_not_found_handle() flaw
Hi All, While trying to implement an function autoload feature, with a lazier function loading and invocation than the example provided in bash doc, I bumped into this bash bug (or feature, you let me know). I asked stackoverflow for some ideas, one pointed me to command_not_found_handle() that I was not aware off and looked promising for what I wanted to achieve. This SO post is quite big, so I will report here a shorter version. In a nutshell to implement a function autoloading I want to plug into command_not_found_handle(), but I need command_not_found_handle()be evaluated in the shell context, not in a subshell. At the moment BASH_VERSION='5.0.16(14)-release' (and all way back) the is wrongly called as a sub-shell, that doesn't hurt the command-not-found packages found in many distro as at this point they don't care about setting things in the shell instance, so their implementation is good enough. To demonstrate the bug, suffice to do this function command_not_found_handle { echo $$ ; sh -c 'echo $PPID' } When run in shell context we got the correct answer $ function command_not_found_handle > { echo $$ ; sh -c 'echo $PPID' > } $ $ command_not_found_handle 11370 11370 But when called from 'not found' context we got $ ddd # dd not found on my system then call command_not_found_handle 11779 11783 $ As we see here, $$ lies pretend to be the shell PID 11779 while it real $$ is 11783, so a child. This is a real problem because then there is nothing I can do in command_not_found_handle) to setup things in the shell context, i.e not new alias setup, no new functin define, etc... I propose a fix, yet bear in mind hacking bash is not my day to day job :) so it must be reviewed by gurus. I send the proposed [atch separatly. With this fix I got this run PW$ PS1='$ ' $ function command_not_found_handle > { echo $$ ; sh -c 'echo $PPID' > } $ ddd 12165 12165 $ function command_not_found_handle > { echo in cnf > A="cnf-was-called" > return 127 > } $ A='' $ ddd in cnf $ echo $A cnf-was-called $ Meaning now command_not_found_handle() is a real function called from the shel context, shell context can then be touch (vars, alias, functions, etc..) what I need to implement my autoload mechanism. Not that it is indeed possible to chain the handlers, so assuming a command-not-found package installed I got this on ubuntu. $ declare -f command_not_found_handle command_not_found_handle () { if [ -x /usr/lib/command-not-found ]; then /usr/lib/command-not-found -- "$1"; return $?; else if [ -x /usr/share/command-not-found/command-not-found ]; then /usr/share/command-not-found/command-not-found -- "$1"; return $?; else printf "%s: command not found\n" "$1" 1>&2; return 127; fi; fi } And a run gives $ ddd Command 'ddd' not found, but can be installed with: sudo apt install ddd If I now want to install my handler I rename the current handler # Rename current command_not_found_handle _cnf_body=$(declare -f command_not_found_handle | tail -n +2) eval "function _cnf_prev $_cnf_body" Then I create mine chaining to the prev one function command_not_found_handle { echo in cnf A="cnf-was-called" _cnf_prev "$@" } $ unset A $ ddd in cnf Command 'ddd' not found, but can be installed with: sudo apt install ddd $ echo $A cnf-was-called This shows that my handler was called, on failure to find a function, it forward to the previous handler, then it shows that it ran in the shell contect as A= is set correfctly. I got no memory leak detected with this patch, but again review thouroughly. Hope this helps. Cheers, Phi
Patch: command_not_found_handle() flaw
diff --git a/execute_cmd.c b/execute_cmd.c index 3864986d..ef32631a 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -5370,6 +5370,20 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out, command = search_for_command (pathname, CMDSRCH_HASH|(stdpath ? CMDSRCH_STDPATH : 0)); QUIT; + +#define PHI_CNF 1 +#if(PHI_CNF) + if (command == 0) + { hookf = find_function (NOTFOUND_HOOK); + if(hookf) +{ wl = make_word_list (make_word (NOTFOUND_HOOK), words); + result=execute_shell_function (hookf, wl); + wl->next=0; + dispose_words(wl); + goto parent_return; +} + } +#endif // PHI_CNF if (command) { @@ -5448,7 +5462,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out, if (command == 0) { +#if(!PHI_CNF) +// with PHI_CNF==1 hookf==0 hookf = find_function (NOTFOUND_HOOK); +#endif if (hookf == 0) { /* Make sure filenames are displayed using printable characters */
Re: command_not_found_handle() flaw
On Tue, Mar 10, 2020 at 06:37:24PM +0100, Phi Debian wrote: > In a nutshell to implement a function autoloading I want to plug into > command_not_found_handle(), but I need command_not_found_handle()be > evaluated in the shell context, not in a subshell. You can't. Bash has already forked the subshell before searching for the command that's not found. The command_not_found_handle runs in the already existing subshell. > To demonstrate the bug, suffice to do this It's not a bug.
Re: command_not_found_handle() flaw
On 3/10/20 1:37 PM, Phi Debian wrote: > In a nutshell to implement a function autoloading I want to plug into > command_not_found_handle(), but I need command_not_found_handle()be > evaluated in the shell context, not in a subshell. OK, so this is not an appropriate feature for what you want to do. It's not a bug, since it's behaving as intended. -- ``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: command_not_found_handle() flaw
Hi All, I think it is a bug, it is not working as intended at least in the man page, it says. If that function exists, it is invoked with the original command and the original command's arguments as its arguments, and the function's exit status becomes the exit status of the shell. If that function is not defined, the shell prints an error message and returns an exit status of 127. A function invocation, don't imply a sub shell. Secondly, if yuio insist on going on the subshell path, then $$ and $PPID ought to be setup appropriately, here ther are plain bogus. Third, the argument saying to late we forked already is dumb, it is too late because the sequence hookf = find_function (NOTFOUND_HOOK); execute_shell_function (hookf, wl); is misplaced after the fork, while it should be done before the fork. I provided a fix that no one tested, that don't jeoparise the existing code or behavior, and to respect what a function invocation is. I can survive a "don't fix" well I can fix for myself, but has it is you must at least fix 2 points, fix the doc, sayin the command_not_found_handle() is called in a subshell and fix $$ and $PPID that are bogus in the subshell. BTW fixing $$ and $PPID will take more effort that just placing the hook before the fork, but that's your decision indeed :) I think that either command_not_found_handle() is a gross hack to satisfy command-not-found distro package, and in this case it should simply not be documented in the docco, or else it should be done as specifed i.e a function incovation is not a subshell running a function, that frankly is a bit ridiculous. Cheers, Phi
Re: command_not_found_handle() flaw
On Tue, Mar 10, 2020 at 08:57:26PM +0100, Phi Debian wrote: > Secondly, if yuio insist on going on the subshell path, then $$ and $PPID > ought to be setup appropriately, here ther are plain bogus. wooledg:~$ command_not_found_handle() { echo "\$\$=$$ BASHPID=$BASHPID"; } wooledg:~$ echo "\$\$=$$ BASHPID=$BASHPID" $$=859 BASHPID=859 wooledg:~$ wyeiruwyer $$=859 BASHPID=15619 It looks correct to me. $$ is the PID of the main script, and $BASHPID is the PID of the subshell.
Re: command_not_found_handle() flaw
On 3/10/20 3:57 PM, Phi Debian wrote: > > Hi All, > > I think it is a bug, it is not working as intended at least in the man > page, it says. > > If that function exists, it is invoked > with the original command and the original command's arguments as its > arguments, and the function's exit status becomes the exit status of > the shell. If that function is not defined, the shell prints an error > message and returns an exit status of 127. It's not clear what version of bash you're using, but the current version of the man page says clearly that the function is invoked in "a separate execution environment" and the "exit status becomes the exit status of that subshell." > > A function invocation, don't imply a sub shell. > > Secondly, if yuio insist on going on the subshell path, then $$ and $PPID > ought to be setup appropriately, here ther are plain bogus. $$ doesn't change for separate execution environments like command and process substitution, so it doesn't change here. The same with PPID. -- ``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: command_not_found_handle() flaw
On 3/10/20 4:04 PM, Greg Wooledge wrote: > On Tue, Mar 10, 2020 at 08:57:26PM +0100, Phi Debian wrote: >> Secondly, if yuio insist on going on the subshell path, then $$ and $PPID >> ought to be setup appropriately, here ther are plain bogus. > > wooledg:~$ command_not_found_handle() { echo "\$\$=$$ BASHPID=$BASHPID"; } > wooledg:~$ echo "\$\$=$$ BASHPID=$BASHPID" > $$=859 BASHPID=859 > wooledg:~$ wyeiruwyer > $$=859 BASHPID=15619 > > It looks correct to me. $$ is the PID of the main script, and $BASHPID > is the PID of the subshell. I think perhaps what the reporter did not realize is that this is the expected behavior of a subshell. $ command_not_found_handle; (command_not_found_handle); sddssdfcdsfsf $$=20819 BASHPID=20819 $$=20819 BASHPID=40810 $$=20819 BASHPID=40811 i.e. $$ doesn't change, whether invoked via command_not_found_handle or any other form of subshell. -- Eli Schwartz Arch Linux Bug Wrangler and Trusted User signature.asc Description: OpenPGP digital signature
Add non-interactive PROMPT_COMMAND
PROMPT_COMMAND=sleep\ 1 is great, it lets us slow down scripts... but alas only if they are interactive. One might say: "Sure, instead of $ bash script just use $ sed 's/^/sleep 1; /' script | bash" But that assumes one command per line, and could easily mangle things. Instead bash simply needs a PROMPT_COMMAND that works non-interactively too. Anyway, we could use it to e.g., "check how much oil we have left before executing each command" etc. tons of great uses! Maybe even have fullblown PRE and POST commands, that fire before and after each command.