sgleizes/xsh

XSH unsets IFS during init/bootstrap

Larusso opened this issue · 2 comments

xsh/xsh.sh

Lines 600 to 606 in 86fbd48

{
IFS=:
set -o noglob
set -- $rcs
set +o noglob
unset IFS
}

I have a weird case where xsh breaks the usage of rbenv, pyenv and nodenv installation extensions (ruby-build, python-build, node-build.
The tools throw weird download errors and can't install a ruby, python or node version.
I tracked this issue down to this specific line in the _xsh_load_unit function.
The reasons seems to be the handling of spaces in a command executed from a script.
the build-node script constructs a curl invocation like this

curl -q -o node-v16.13.0-darwin-x64.tar.gz -sSLf    "https://nodejs.org/dist/v16.13.0/node-v16.13.0-darwin-x64.tar.gz"

See the spaces before the URL argument. These spaces come from some string interpolation with empty values.

see:
https://github.com/nodenv/node-build/blob/cf03552c03fb7908ff79c13e3bf55207c057c447/bin/node-build#L445

It's the CURL_OPTS variable which results by default in a string with two spaces.

If I change the mentioned block in _xsh_load_unit to this code everything works fine for me:

  {
    oldIFS="$IFS"
    IFS=":"
    set -o noglob
    set -- $XSH_SHELLS
    set +o noglob
    IFS="$oldIFS"
  }

I didn't quite understand why the parameters need to be reset in this function. For me the XSH_SHELLS variable only ever contains a single entry which is the current shell.

I'm running:

OS: macOS 11.6
bash: GNU bash, version 5.1.12(1)-release (x86_64-apple-darwin20.6.0)
zsh: 5.8 (x86_64-apple-darwin19.6.0)

I will test this on my arch linux box as well and see if I have the same error.

I can also confirm this issue on linux.
bash: GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
zsh: 5.8 (x86_64-pc-linux-gnu)

Thanks for reporting, this was indeed an oversight on my part.

To answer your interrogation about XSH_SHELLS, its value is a colon-separated list of shell candidates to lookup for units.
You are right that for most usages, XSH_SHELL is just set to the current shell.
However you can specify multiple shells when registering a module, XSH will lookup the unit in the given order of preference. The following example will load the core module runcoms from the posix shell if they don't exist for bash.

xsh module core -s bash:posix

You can also use -s/--shells with the bootstrap and create commands.