You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
shell buitins have no effect when running an interactive parser with a custom readline implementation #1100
for example, if I alias a command to something else:
alias ls='echo this is an alias'
and then if I run ls the alias isn't honored, it just runs the ls binary.
$ alias ls='echo nothing' 18:27
$ ls 18:27
ash_history bin cmd go.mod go.sum justfile pkg
$ alias 18:27
alias ls='eza'
$ 18:27
This could be a result of the way I'm using this library, but I've tried every documented way to parse and run shell statements with my custom implementation of readline. This implementation is probably 3500 sloc at minimum and I can't fit it into the given parser.Interactive method.
here is an example of the implementation:
r, err:=interp.New(interp.StdIO(os.Stdin, os.Stdout, os.Stderr))
iferr!=nil {
log.Fatal(err)
}
parser:=syntax.NewParser(syntax.Variant(syntax.LangBash))
for {
line, err:=shell.Readline() // for this example this is a black box that returns a stringiferr==io.EOF {
break
} elseiferr!=nil {
returnerr
}
iferr:=parser.Stmts(strings.NewReader(line), func(stmt*syntax.Stmt) bool {
ifparser.Incomplete() {
returntrue
}
// pass Ctrl+C to the child process and ignore itctx, cancel:=context.WithCancel(context.Background())
gofunc() {
select {
case<-signals:
cancel()
returncase<-ctx.Done():
return
}
}()
r.Run(ctx, stmt)
ifr.Exited() {
returnfalse
}
returntrue
}); err!=nil {
log.Println(err)
}
}
is there some part of the API I am missing here, or is what is necessary to allow this not exposed and what could possibly be causing shell builtins not to work in this context?
exit, read -r VARNAME also doesn't work, but cd , export, pushd popd dirs work just fine.
edit:
upon doing some testing I see that alias also doesn't work with gosh either, so maybe this is a known issue.
Thanks for the report. Indeed cmd/gosh did not expand aliases by default, even though it should behave like an interactive shell. The commits above should have fixed that, although note that you will need to use the option like cmd/gosh does now.
Can you clarify what you mean by exit and read not working properly in an interactive shell? They seem to work just fine in cmd/gosh at master, at least:
$ echo $0
/usr/bin/bash
$ gosh
$ echo $0
gosh
$ read -r FOO <<EOF
> here is some text
> EOF
$ echo $FOO
here is some text
$ exit 34
$ echo $0
/usr/bin/bash
I'm glad it was a simple fix. My problem is that the parser.Interactive method only allows for very rudimentary forms of line editing. So I, and the two other gosh implementations I found in the wild, were trying to re-implement parser.Interactive but with better readline capabilities:
but the problem all of these implementations run into the issues I outlined above: aliases don't expand, read -r VAR doesn't read into a variable, exit also doesn't actually exit the interactive shell and asfaik there is no real way to propagate that exit code upwards.
I made a little test repo that shows the problem and gives a way clearer idea of what I am trying to do you can check it out here https://github.com/sweetbbak/ash/blob/main/cmd/readline/main.go, or you could quick install it with this if you want to see it first hand:
go install github.com/sweetbbak/ash/cmd/readline@6615b6b5e7588118ecb081ceed14c8cc0c3aa864
but ultimately, I would like to implement sh with a way more capable version of readline that allows for ^L clearing the screen, vim + emacs mode, etc... and the given API of parser.Interactive isn't capable of doing that (as far as I know, I could be wrong here) and replicating that behavior externally causes the issues I outlined. Thanks you for the awesome library and tooling by the way, it is awe inspiring to me.
edit: my apologies, I realized that read does work and I just made a stupid mistake of not exporting the variable, I'm guessing exit can be implemented externally, and aliases are fixed so I'll just close the issue.
Activity
cmd/gosh: add bad test case for #1100
interp: add an Interactive option to be used by cmd/gosh
mvdan commentedon Oct 8, 2024
Thanks for the report. Indeed cmd/gosh did not expand aliases by default, even though it should behave like an interactive shell. The commits above should have fixed that, although note that you will need to use the option like cmd/gosh does now.
Can you clarify what you mean by
exitandreadnot working properly in an interactive shell? They seem to work just fine in cmd/gosh at master, at least:sweetbbak commentedon Oct 9, 2024
I'm glad it was a simple fix. My problem is that the parser.Interactive method only allows for very rudimentary forms of line editing. So I, and the two other
goshimplementations I found in the wild, were trying to re-implementparser.Interactivebut with better readline capabilities:(u-root) https://github.com/u-root/u-root/tree/main/cmds/core/gosh
(gonix) https://git.mills.io/prologic/gonix/src/branch/main/internal/applets/sh/sh.go
but the problem all of these implementations run into the issues I outlined above: aliases don't expand,
read -r VARdoesn't read into a variable,exitalso doesn't actually exit the interactive shell and asfaik there is no real way to propagate that exit code upwards.I made a little test repo that shows the problem and gives a way clearer idea of what I am trying to do you can check it out here https://github.com/sweetbbak/ash/blob/main/cmd/readline/main.go, or you could quick install it with this if you want to see it first hand:
but ultimately, I would like to implement
shwith a way more capable version of readline that allows for^Lclearing the screen, vim + emacs mode, etc... and the given API ofparser.Interactiveisn't capable of doing that (as far as I know, I could be wrong here) and replicating that behavior externally causes the issues I outlined. Thanks you for the awesome library and tooling by the way, it is awe inspiring to me.edit: my apologies, I realized that
readdoes work and I just made a stupid mistake of not exporting the variable, I'm guessing exit can be implemented externally, and aliases are fixed so I'll just close the issue.chore(deps): update module mvdan.cc/sh/v3/cmd/shfmt to v3.12.0 (hetzn…