Re: Assign Default Value expansion inserts ASCII DEL for empty 'word'

2020-03-10 Thread Chet Ramey
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

2020-03-10 Thread Phi Debian
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

2020-03-10 Thread Phi Debian
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

2020-03-10 Thread Greg Wooledge
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

2020-03-10 Thread Chet Ramey
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

2020-03-10 Thread Phi Debian
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

2020-03-10 Thread Greg Wooledge
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

2020-03-10 Thread Chet Ramey
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

2020-03-10 Thread Eli Schwartz
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

2020-03-10 Thread 積丹尼 Dan Jacobson
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.