Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please support the yash3 posix shell written in rust with the repo at https://github.com/magicant/yash-rs. #3499

Open
brancoliticus opened this issue Dec 19, 2024 · 19 comments

Comments

@brancoliticus
Copy link

I was trying to run nvm in the yash3 shell and it doesn't work, even though the nvm script is advertised as being posix compliant.

I installed yash3 from crates.io and nvm with the suggested install script at https://github.com/nvm-sh/nvm/blob/master/README.md piped into bash.

Question: if I uninstall nvm and reinstall by running the install script in yash3 should it conclude in a valid installation?

Feel free to bug me below in the comments about how I may help make yash3 support happen.

$ printf "${NVM_DIR}\n"
/home/tardigrade/.nvm
$ \. $NVM_DIR/nvm.sh
error: The parameter expansion is not closed
   --> /home/tardigrade/.nvm/nvm.sh:425:37
    |
425 |     NVM_SCRIPT_SOURCE="${BASH_SOURCE[0]}"
    |                                     ^ expected `}`
    |                        -- info: the parameter started here
    |
   ::: <stdin>:8:4
    |
  8 | \. $NVM_DIR/nvm.sh
    |    --------------- info: script `/home/tardigrade/.nvm/nvm.sh` was sourced here
    |
$ printf "${0}\n"
yash3
$
@ljharb
Copy link
Member

ljharb commented Dec 19, 2024

that line is inside a if [ -n "${BASH_SOURCE-}" ]; then block, which means it shouldn't be evaluating in non-bash. Is yash3, or yourself, setting $BASH_SOURCE? Or, is yash3 evaluating lines of code it doesn't need to?

@brancoliticus
Copy link
Author

BASH_SOURCE doesn't seem to be set when I run it in my environemnt:

$ printf "${0}\n${BASH_SOURCE}\n"
yash3

I run yash3 inside the zellij terminal multiplexer on top of bash. Mabe that has something to do with it?

@ljharb
Copy link
Member

ljharb commented Dec 19, 2024

That means it is set, to yash3 - that's the problem. That env var shouldn't be set unless you're running actual bash.

@brancoliticus
Copy link
Author

brancoliticus commented Dec 19, 2024

There is a ${0} in my printf to show that I'm running in yash3. The empty line below must be the result of running printf on ${BASH_SOURCE}.

@brancoliticus
Copy link
Author

The following is confusing me:

$ [ -n ${BASH_SOURCE-} ] && printf "BASH_SOURCE set\n"
BASH_SOURCE set
$ printf "${BASH_SOURCE}\n"

$ printf "${BASH_SOURCE-}\n"

$ [ -n ${BASH_SOURCE} ] && printf "BASH_SOURCE set\n"
BASH_SOURCE set
$ printf "${0}\n"
yash3
$

@brancoliticus
Copy link
Author

brancoliticus commented Dec 19, 2024

Isn't test, that is [...] going to the system bash shell and seeing $BASH_SOURCE set from there? printf mabe doesn't go to the system bash shell.

@ljharb
Copy link
Member

ljharb commented Dec 19, 2024

commands don't "go to other shells" generally. in this case, can you try printf "|${BASH_SOURCE-}|" to confirm it's actually the empty string, and not whitespace?

@brancoliticus
Copy link
Author

$ printf "${0}\n"
yash3
$ printf "|${BASH_SOURCE-}|\n"
||
$

@ljharb
Copy link
Member

ljharb commented Dec 19, 2024

is there a chance that's a bug in yash3 with the -n test then?

@brancoliticus
Copy link
Author

test with it's [whaterver inside] alias is a system command, it's not written by yash3, I'm 100 percent positive. It is in gnu coreutils on my Debian 12 Linux system. It says so in the manpage. What is an issue is how it receives the variable expansion for $BASH_SOURCE from yash3.

@ljharb
Copy link
Member

ljharb commented Dec 19, 2024

-n is testing that a variable is set and nonempty, and in this case it's empty, so there's clearly a shell bug _some_where :-)

@ljharb
Copy link
Member

ljharb commented Dec 19, 2024

so, on the yash3 readme, it says:

To run a shell script, run yash3 with the script file as an argument. Without an argument, yash3 will start a read-eval loop, but interactive features are not yet implemented.

that implies that you can't yet source nvm.sh, and run commands.

@brancoliticus
Copy link
Author

I'll post a bug report at the yash3 repo, the developer is very active and he might chime in.

@magicant
Copy link

Hi

Most existing shells, including bash, parse the brackets [0] in ${BASH_SOURCE[0]} only when they actually expand the parameter, but yash3 tries to eagerly catch syntax errors before executing commands. This means that the unsupported brackets are detected when the entire if command containing the parameter is parsed, before the execution of the if command is started and the [ -n "${BASH_SOURCE-}" ] condition is evaluated.

My recommended solution is to wrap the bashism in single quotes with the eval command as in: eval 'NVM_SCRIPT_SOURCE="${BASH_SOURCE[0]}"'. This way, the brackets are only parsed when the eval command is executed, which is after the [ -n "${BASH_SOURCE-}" ] condition has been satisfied.

@ljharb
Copy link
Member

ljharb commented Dec 20, 2024

What does POSIX say about that syntax validation behavior? If nothing, then "what existing shells do" is what I'd say is reasonable to support and to implement (obv if it says to do one or the other, then "posix-compliant" requires doing that thing).

Using eval isn't a reasonable ask - we only have 3 instances of it at the moment, and I look at those as warts that need to be excised.

@magicant
Copy link

https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_08_01

An expansion error is one that occurs when the shell expansions defined in 2.6 Word Expansions are carried out (for example, "${x!y}", because '!' is not a valid operator); an implementation may treat these as syntax errors if it is able to detect them during tokenization, rather than during expansion.

@ljharb
Copy link
Member

ljharb commented Dec 20, 2024

Alrighty - that "may" is doing a lot of work there, but you answered my question.

Is there another way to do this without using eval?

@magicant
Copy link

Bash assumes the first element when expanding an array without an index, so ${BASH_SOURCE[0]} could also be written as ${BASH_SOURCE}.

@ljharb
Copy link
Member

ljharb commented Dec 20, 2024

Awesome! As soon as I get tests passing on master, I'll push up that fix and release it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants