[Bug?]: (Windows) Yarn run/exec puts literal quotes around parameters
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 8.1k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
Self-service
- I'd be willing to implement a fix
Describe the bug
Since I upgraded to berry from v1 some of my scripts are failing. To be exact, I have a script that invokes the Windows copy command like so (in "scripts" in package.json):
"other command && copy /Y src_files dest"
This used to work until the update and is now failing with "The system cannot find the file specified".
I investigated a bit and here's what I found.
Yarn exec/run v1 vs. v2
Create a file test.bat with the following content:
@echo %*
This just prints all arguments it receives. Let's try to execute it using cmd directly, then using yarn exec and yarn run for v1 and berry.
The following table contains the command used and the generated output for each method.
| Command | cmd | (v1) yarn exec | (v2) yarn exec | (v1) yarn run | (v2) yarn run |
|---|---|---|---|---|---|
| test.bat arg | arg | arg | "arg" | arg | "arg" |
| test.bat "a b c" | "a b c" | "a b c" | "a b c" | "a b c" | "a b c" |
| test.bat o="a b c" | o="a b c" | "o=a b c" | "o=a b c" | o="a b c" | "o=a b c" |
| echo test | test | (error) | test | test | test |
| echo "test" | "test" | (error) | test | "test" | test |
| cmd /c echo "arg" | "arg" | arg | arg | "arg" | arg |
| cmd /c test.bat arg | arg | arg | arg | arg | arg |
Notes:
For the
cmdcolumn, the command is executed directly from withincmd.exe(e.g. typingtest.batdirectly in shell)For the
yarn execcolumn, the command is executed like so:yarn exec <command>(e.g. typingyarn exec test.batin shell).The (error) in the yarn v1 column stands for
error Couldn't find the binary echo.For the
yarn runcolumn, I just used a newpackage.jsonwith"scripts": { "thing": "<command>" }and ran it withyarn run thing.
The problem
I'm guessing that the copy command is called with "/Y" as an argument, instead of just /Y, as running copy "/Y" src dest produces the same error. The most important is the first row in the table above - that shows exactly what the problem is.
Workaround
See the last row in the table - you can append cmd /c in front of commands where the extra quotes cause problems. This works for simple commands, but I've yet to make it work with my copy command due to other issues (#6233). The actual workaround I used was using shx instead of run-script-os.
My previous setup used run-script-os with 2 scripts - one for Windows with copy and another for the rest with cp. I have switched to a single script using shx (which implements all Unix utilities in JS so they work cross-platform), so now I use shx cp and no longer have to have a separate Windows script.
Environment
System:
OS: Windows 10 10.0.19045
CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700KF
Binaries:
Node: 20.8.0 - ~\AppData\Local\Temp\xfs-2e9c83c0\node.CMD
Yarn: 4.1.1 - ~\AppData\Local\Temp\xfs-2e9c83c0\yarn.CMD
npm: 10.2.1 - C:\Program Files\nodejs\npm.CMD
(installed with nvm)
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the Windows behavior with the mentioned test.bat file and the yarn exec and yarn run entry points, comparing the command matrix in the issue. Trace how Yarn handles arguments for cmd.exe, then verify that simple arguments no longer receive literal quotes while the documented command cases still work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100