Re: ./script doesn't work in completion function

2024-01-22 Thread Martin D Kealey
Chet has since pointed out that the debugger is not involved at all.

On Mon, 22 Jan 2024, 18:17 Grisha Levit,  wrote:

>
> That's not quite what happens. These scripts get executed by forking the
> current bash process (without exec). The new shell resets its state and
> runs the script.
>

I'm broadly aware that this is what happens; however it's not impossible
that such could be handled by a short script built into the Shell, rather
than as native C code.

The debugger message is afaict an artifact of not quite resetting
> completely -- if you had extdebug on in the shell from which you ran `./b`,
> the forked shell will try to load the debugger start file (as when running
> `bash -O extdebug ./b`)
>

Okay that makes sense; I leave extdebug turned on in my interactive Shell
so that caller will report more info.

Note that the script still runs, `B` is printed.
>

Yeah I saw that.

So these are both sides effects of the same thing: not properly resetting
the Shell state when creating an interpreter for a script without a #!

-Martin

>


Re: ./script doesn't work in completion function

2024-01-22 Thread Chet Ramey

On 1/22/24 8:02 AM, Oğuz wrote:

On Mon, Jan 22, 2024 at 3:25 PM Greg Wooledge  wrote:

But in any case, writing a "script" without a shebang and then counting
on the shell to work around the broken script is not ideal.

Unlike shebangs that behavior is standardized. Which is what I
consider ideal. Thanks for your input


For those who are wondering:

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01

"If the execl() function fails due to an error equivalent to the [ENOEXEC]
error defined in the System Interfaces volume of POSIX.1-2017, the shell
shall execute a command equivalent to having a shell invoked with the
pathname resulting from the search as its first operand, with any remaining
arguments passed to the new shell, except that the value of "$0" in the new
shell may be set to the command name. If the executable file is not a text
file, the shell may bypass this command execution. In this case, it shall
write an error message, and shall return an exit status of 126."

--
``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/



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: ./script doesn't work in completion function

2024-01-22 Thread Chet Ramey

On 1/22/24 1:53 AM, Martin D Kealey wrote:

Hi Oğuz

On Sun, 21 Jan 2024 at 03:20, Oğuz  wrote:


 $ echo echo foo bar >s
 $ chmod +x s



You seem to have created an invalid executable. It seems that scripts
without a #! can only be run with help from the debugger library;


This isn't correct. I don't know how you managed to enable debugging mode,
unless it was enabled in the interactive shell you're running, but since
you did, the subshell inherited it and attempted to start the debugger.
Scripts without a `#!' don't have anything to do with the debugger.

--
``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/



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: ./script doesn't work in completion function

2024-01-22 Thread Chet Ramey

On 1/20/24 12:20 PM, Oğuz wrote:

See:

 $ echo echo foo bar >s
 $ chmod +x s
 $ f(){ COMPREPLY=($(bash ./s));}
 $ complete -F f g
 $
 $ g
 bar  foo
 $ g ^C
 $
 $ f(){ COMPREPLY=($(./s));}
 $ g ^C^C
 $

I press tab after typing `g ' in both cases, this moves the cursor to
the right in the second case instead of showing the completion
options.


Thanks for the report. The script works, it just leaves the terminal in
icanon mode, so the tabs don't cause word completion until you hit newline.

The problem is the subshell inherits the readline state, so it can tell
whether or not the terminal is in icanon mode should it need to, but resets
it to icanon mode at exit without making sure it was the one that set it to
-icanon in the first place.

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/



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: ./script doesn't work in completion function

2024-01-22 Thread Oğuz
On Mon, Jan 22, 2024 at 3:25 PM Greg Wooledge  wrote:
> But in any case, writing a "script" without a shebang and then counting
> on the shell to work around the broken script is not ideal.
Unlike shebangs that behavior is standardized. Which is what I
consider ideal. Thanks for your input



Re: ./script doesn't work in completion function

2024-01-22 Thread Greg Wooledge
On Mon, Jan 22, 2024 at 12:17:12PM +0200, Oğuz wrote:
> On Monday, January 22, 2024, Martin D Kealey 
> wrote:
> >
> > You seem to have created an invalid executable. It seems that scripts
> > without a #! can only be run with help from the debugger library
> >
> 
> Hi Martin, POSIX shells interpret such executables as shell scripts, I
> don't think bash would take a hacky approach like that for implementing
> this basic functionality. It must be something else

Bash attempts to execute the command normally, and when the kernel
returns ENOEXEC, bash decides to try a different approach.  It opens
the file, reads a hundred or so bytes, and scans them for NUL bytes.
If it doesn't find a NUL, it forks a subshell of itself, and uses
that to read the file as a script.  If a NUL is found, bash aborts with
an error message.

Without a NUL:

unicorn:~$ printf 'echo foo' > foo
unicorn:~$ strace -f bash -c ./foo
execve("/usr/bin/bash", ["bash", "-c", "./foo"], 0x7ffe1badab60 /* 53 vars */) 
= 0
[...]
execve("./foo", ["./foo"], 0x562def3ca230 /* 53 vars */) = -1 ENOEXEC (Exec 
format error)
openat(AT_FDCWD, "./foo", O_RDONLY) = 3
read(3, "echo foo", 128)= 8
close(3)= 0
[...]

With a NUL:

unicorn:~$ printf 'echo foo\0' > foo
unicorn:~$ bash -c ./foo
bash: line 1: ./foo: cannot execute binary file: Exec format error

I don't currently have a build of bash-5.3 (prerelease) to test the
original bug report, so I can neither confirm nor deny it.

But in any case, writing a "script" without a shebang and then counting
on the shell to work around the broken script is not ideal.  You get
differing behaviors depending on which shell you're currently in.
Bash forks a subshell.  Zsh and GNU find fork /bin/sh.  Systemd will
just report the original error and will not do any workarounds.



Re: ./script doesn't work in completion function

2024-01-22 Thread Oğuz
On Monday, January 22, 2024, Martin D Kealey 
wrote:
>
> You seem to have created an invalid executable. It seems that scripts
> without a #! can only be run with help from the debugger library
>

Hi Martin, POSIX shells interpret such executables as shell scripts, I
don't think bash would take a hacky approach like that for implementing
this basic functionality. It must be something else


-- 
Oğuz


Re: ./script doesn't work in completion function

2024-01-22 Thread Grisha Levit
On Mon, Jan 22, 2024, 01:54 Martin D Kealey  wrote:

> You seem to have created an invalid executable. It seems that scripts
> without a #! can only be run with help from the debugger library;


That's not quite what happens. These scripts get executed by forking the
current bash process (without exec). The new shell resets its state and
runs the script.

$ ./b
> ./b:
>
> /home/martin/lib/bash/f3a35a2d601a55f337f8ca02a541f8c033682247/share/bashdb/bashdb-main.inc:
> No such file or directory
> ./b: warning: cannot start debugger; debugging mode disabled
> B


The debugger message is afaict an artifact of not quite resetting
completely -- if you had extdebug on in the shell from which you ran `./b`,
the forked shell will try to load the debugger start file (as when running
`bash -O extdebug ./b`)

Note that the script still runs, `B` is printed.

>


Re: ./script doesn't work in completion function

2024-01-21 Thread Martin D Kealey
Hi Oğuz

On Sun, 21 Jan 2024 at 03:20, Oğuz  wrote:

> $ echo echo foo bar >s
> $ chmod +x s
>

You seem to have created an invalid executable. It seems that scripts
without a #! can only be run with help from the debugger library; for
example, this is what I get when I run up bash_5.1.3p47 (built from commit
f3a35a2d601a55f337f8ca02a541f8c033682247):


$ cat a
#!/bin/sh
echo A
$ cat b
==> b <==
echo B

$ ./a
A

$ ./b
./b:
/home/martin/lib/bash/f3a35a2d601a55f337f8ca02a541f8c033682247/share/bashdb/bashdb-main.inc:
No such file or directory
./b: warning: cannot start debugger; debugging mode disabled
B



So I'm guessing that if the debugger is triggered in the middle of a
completion function, it's likely to get stuck. (Maybe it's writing a prompt
to stdout?)

I get the same result for
 bash_5.0.0rc1 (built from commit f250956cb2a8dca13fc0242affc225f9d6983604)
 bash_4.4.23p49 (build from commit 64447609994bfddeef1061948022c074093e9a9f)
 bash_4.4.0p51 (built from commit a0c0a00fc419b7bc08202a79134fcd5bc0427071)

Not exhibited by bash_4.3.x

-Martin


./script doesn't work in completion function

2024-01-20 Thread Oğuz
See:

$ echo echo foo bar >s
$ chmod +x s
$ f(){ COMPREPLY=($(bash ./s));}
$ complete -F f g
$
$ g
bar  foo
$ g ^C
$
$ f(){ COMPREPLY=($(./s));}
$ g ^C^C
$

I press tab after typing `g ' in both cases, this moves the cursor to
the right in the second case instead of showing the completion
options.

This is reproducible on both the devel branch and 5.1.16, I didn't test 5.2.

Oğuz