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

[BUG] npx opening the PowerShell script with the default editor instead of executing it. #3843

Open
1 task done
akunaatrium opened this issue Oct 6, 2021 · 5 comments
Open
1 task done
Labels
Bug thing that needs fixing cmd:exec related to `npx` Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release

Comments

@akunaatrium
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

I created a package containing a bunch of PowerShell scripts. In the package.json file of the package, there's such a block:

"bin": {
    "say-hello": "./hello.ps1"
}

The package is pushed to an npm registry.

In another location, I want to use the package and have a very simple way to be able to execute scripts from the package, let's say the hello.ps1 that is defined as a binary in the package. So, when I installed the package using another package.json file like this:

{
  "name": "blaa",
  "private": true,
  "version": "1.0.0",
  "devDependencies": {
    "tooling": "0.0.11"
  }
}

where tooling is the name of the package to be installed, the node_modules/.bin folder gets populated with three files:

  • say-hello
  • say-hello.cmd
  • say-hello.ps1

Now, using PowerShell in the same folder where the package.json resides, I execute npx say-hello but I get:

This program is blocked by group policy. For more information, contact your system administrator.

The computer is corporate managed and enforces a lot of policies. Looks like the say-hello.cmd file was attempted to be executed but failed. I know that I can execute PowerShell scripts. Why is npx defaulting to run the .cmd file if it can detect that the shell is PowerShell? Is it possible to configure npm/npx to execute the .ps1 file instead? Trying to run npx say-hello.ps1 command opens the script in Notepad++ in my case, instead of executing it.

Expected Behavior

npx should understand that PowerShell is the current shell and executes the say-hello.ps1 file. Or at least executes it when specifying the extension of the file, like in this command: npx say-hello.ps1.
If this is not possible, then there should be a configurable option in a .npmrc or package.json to specify which shell must be used to execute scripts.

Steps To Reproduce

No response

Environment

  • OS: Windows 10
  • Node: v14.17.0
  • npm: 7.24.2
@akunaatrium akunaatrium added Bug thing that needs fixing Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release labels Oct 6, 2021
@BinToss
Copy link

BinToss commented Nov 30, 2021

Trying to run npx say-hello.ps1 command opens the script in Notepad++ in my case, instead of executing it.
npx say-hello.ps1 is processed by a Command Prompt terminal inside the current terminal shell. The command is then processed by the Windows shell, meaning that it will run with with the file type/extensions's Open shell command.
In your case, it seems the Open shell command (in either the user namespace or the system namespace) uses the following command or something like it: notepad++.exe %1. Check in the Registry at HKCR\Microsoft.PowerShellModule.1\Shell\Open\Command and HKCU\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open\Command for the current file extension app association.

Sometimes, executing a file via the OS shell is desired behavior, though it does invite issues like this in which the file type's associated app isn't what was expected.


npx should understand that PowerShell is the current shell and executes the say-hello.ps1 file. Or at least executes it when specifying the extension of the file, like in this command: npx say-hello.ps1.

I agree that it would be helpful if npx were be aware of its current context in relation to file association, but how will it know when a .ps1 file should be executed with powershell.exe instead of pwsh.exe? In the same line of logic, how would it know to execute a .sh script with BASH instead of ZSH or a similar terminal shell?

The preferred solution is as you suggested: add the ability to specify which shell to use. Better yet, failover to another shell if the current shell encounters an exception.
The former is partly implemented via npx's command line (i.e. npx pwsh hello-world.ps1), but this does not cater to cross-platform reproducibility.
The latter does not require NPM to be changed. A script in your package.json should suffice if NPX can catch exceptions or process If-Then script blocks.
However, this workaround would be a pain to maintain across multiple repositories that depend on your package's app.


In the first place, the real issue that your organization requires the usage of shell scripts, yet it prohibits the use of shell scripts its products depend on.

@nlf
Copy link
Contributor

nlf commented May 31, 2022

if your script-shell setting is still cmd (which is the default) then this problem makes some sense, you might try something like npm config set script-shell pwsh --location=user and then retry running the script.

we do not attempt to run in the same shell the user is already running, rather we default to sh in posix systems and cmd in windows. if you want something else you'll have to set it explicitly.

let me know if that takes care of the issue for you

@OmgImAlexis
Copy link

I don't understand the point of npm generating the extra files like .cmd and .ps1 if it always uses the .cmd?

Or am I missing something here?

@nlf
Copy link
Contributor

nlf commented May 31, 2022

it doesn't always use cmd it uses it by default. you are always free to tell npm to run under whatever shell you want it to. in addition to that, the extra files let globally installed packages work more consistently. just because you did an npm i -g foo in cmd doesn't mean you don't want to be able to run that package's binaries from pwsh or even bash.

from your original post:

If this is not possible, then there should be a configurable option in a .npmrc or package.json to specify which shell must be used to execute scripts.

this is the script-shell option, and why i suggested using it.

fwiw i do agree with you that it would be better if we tried to reuse the same shell you're currently in, however that would be an enormous breaking change and not something we can do lightly (like we're at least 2 semver-major releases away from making that the default)

@zachleat
Copy link

Stumbled into this one today per 11ty/eleventy#2875. I would say it is quite confusing (for me personally) that with our bin value pointing eleventy to cmd.js would also execute eleventy.js from the npx @11ty/eleventy command. That seems bug-ish to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing cmd:exec related to `npx` Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release
Projects
None yet
Development

No branches or pull requests

6 participants