[BUG] npx runs executables in path instead of wanted package [Windows/Linux]
distante opened this issue · comments
Reproducible with node 14.15.4 installed in a windows 10 machine.
Current Behavior
If an executable exist in the path with the name of the wanted script it overrides npx
command.
Steps to Reproduce
- Create a file named
cli.bat
with whatever in a directory that exists on your path. - Run
npx @capacitor/cli
Expected Behavior
@capacitor/cli
output should be visible
What happens
cli.bat
gets executed.
Same or similar issue with node v12.16.3, npm 6.14.11 running on Ubuntu 18.04
Running npx @betterer/cli
produces the output:
Usage is: mono [options] program [program-options]
Development:
--aot[=<options>] Compiles the assembly to native code
--debug[=<options>] Enable debugging support, use --help-debug for details
--debugger-agent=options Enable the debugger agent
--profile[=profiler] Runs in profiling mode with the specified profiler module
--trace[=EXPR] Enable tracing, use --help-trace for details
--jitmap Output a jit method map to /tmp/perf-PID.map
--help-devel Shows more options available to developers
Runtime:
--config FILE Loads FILE as the Mono config
--verbose, -v Increases the verbosity level
--help, -h Show usage information
--version, -V Show version information
--runtime=VERSION Use the VERSION runtime, instead of autodetecting
--optimize=OPT Turns on or off a specific optimization
Use --list-opt to get a list of optimizations
--security[=mode] Turns on the unsupported security manager (off by default)
mode is one of cas, core-clr, verifiable or validil
--attach=OPTIONS Pass OPTIONS to the attach agent in the runtime.
Currently the only supported option is 'disable'.
--llvm, --nollvm Controls whenever the runtime uses LLVM to compile code.
--gc=[sgen,boehm] Select SGen or Boehm GC (runs mono or mono-sgen)
Running the cli
command (/usr/bin/cli
) produces the exact same output
I changed the title to add Linux.
Try npx with npm 7 - if you’re still having issues there, please file an issue in the cli issue. npm 6 as well as this repo are effectively not receiving any more updates.
I'm not sure if this is an issue, I thought it was the expected behavior. That being said, it took Mac users of apply
off-guard, since apply
is an existing tool on that OS. npx apply
tried to use the native apply
utility instead of downloading apply
from NPM, which was a real bummer.
Related issue: preset/preset#65
The workaround is to use --ignore-existing
. Would be nice if it was actually a bug that is not intended, because requiring users to install apply
or use npx apply --ignore-existing
(without even a short flag) kind of ruins the beauty of that command.
I don’t think there’s a reasonable way to distinguish between a builtin and a globally installed binary, so i think it’s just incumbent in authors to pick binary names that don’t already exist :-/
Yeah, that's unfortunate. I think it's possible to distinguish them though, and I don't really see the use case for wanting npx
to trigger other commands.
--ignore-existing
does ignore $PATH
and the current node_modules/.bin
. A good default, in my opinion, would be to ignore $PATH
and look into any $PATH
that contains node_modules/.bin
.
That would cover local installs, but wouldn't cover global installs, which could be in any location (depending on where the user configured npm root -g
, where they installed node, or what --prefix
they specified when running npm install -g
).
My bad, I didn't explain well. I meant that that npx
could look for paths in $PATH
that contain node_modules/.bin
, in addition to the node_modules/.bin
in the current working directory. That would cover the --prefix
as well, unless I misunderstood what it does.
with nvm, global binaries are in $NVM_DIR/versions/node/v14.15.5/lib/node_modules
. With the typical node install, they're in /usr/local
or something. It's only local installs that have node_modules
or .bin
in them.
Ah, I see. I thought they'd always be in this directory relative to the installation path. That said, NPM is aware of which packages are installed globally, right? With that knowledge, it could determine the paths to their binaries?
No, it’s not necessarily aware of that - /usr/local contains all the system binaries.
Hm, I'm confused then. If it's not aware of where it installs packages and their binaries, how does it uninstall them?
That’s a good question :-) it’s aware via various configs, but since some of those can be supplied at the time of the command (which means uninstall would require them too) then npx would require the same invocation args to find everything.
Either way, i think that it’s just a normal consequence of choosing a binary name that conflicts with a builtin one on some systems. “apply”, like any other builtin Mac command, is something I’d suggest is off limits as a binary name.
You're right that the name of the binary should be considered wisely. I just wasn't aware of that behavior from npx
, which is unfortunate. :/
Still, if I understood correctly, what you said means that it's possible for npx
to determine if the supplied package/binary name is something that has been installed... right?
Though while I do think it'd be a better default, that'd also be a breaking change, and I can't see that being implemented soon.