`ChildProcess.spawn` with `NoShell` looks for a program named after the program and its arguments
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 82/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- javascript, node.js
調査の方向性
Issue にリンクされている再現手順から始め、続いてコマンドの構築と shell オプションの処理に関する Gren/Kernel/ChildProcess.js を確認します。NoShell が名前付きプログラムを個別の引数で起動し、DefaultShell が既存の動作を維持することを、提供された Gren プログラムと出力を完了確認として使用して検証します。
索引モデルが issue の本文から書いたものです。
説明
Found against: gren 0.6.6, gren-lang/core 7.4.2, gren-lang/node 6.1.3, node 22
Reproduction: https://github.com/gilramir/gren-bug-reports/tree/main/2026-09-16-childprocess-spawn-noshell-arguments
ChildProcess.spawn with shell = NoShell works for a program with no
arguments and fails for any program given arguments: spawn cp "test" [ "1", "-eq", "1" ] asks node for a program named test 1 -eq 1, which does not
exist. The same call with DefaultShell works. (That the failure crashes the
program instead of reaching onExit is a separate bug, reported separately.)
Reproduction
gren.json dependencies: gren-lang/core 7.4.2, gren-lang/node 6.1.3. Save as src/Main.gren. Build and run with gren make Main --output=app && node app:
module Main exposing (main)
import Bytes exposing (Bytes)
import ChildProcess exposing (Shell(..))
import Init
import Node
import Stream
import Task
rows : Array { label : String, shell : Shell, program : String, arguments : Array String }
rows =
[ { label = "`DefaultShell`, `test 1 -eq 1`", shell = DefaultShell, program = "test", arguments = [ "1", "-eq", "1" ] }
, { label = "`NoShell`, `true`", shell = NoShell, program = "true", arguments = [] }
, { label = "`NoShell`, `test 1 -eq 1`", shell = NoShell, program = "test", arguments = [ "1", "-eq", "1" ] }
]
type Msg
= Spawn Int
| Exited { row : Int, code : Int }
| Started
type alias Model =
{ cp : ChildProcess.Permission, stdout : Stream.Writable Bytes }
main : Node.Program Model Msg
main =
Node.defineProgram { init = init, update = update, subscriptions = \_ -> Sub.none }
init : Node.Environment -> Init.Task { model : Model, command : Cmd Msg }
init env =
Init.await ChildProcess.initialize <| \cp ->
Node.startProgram
{ model = { cp = cp, stdout = env.stdout }
, command = print env.stdout "| spawn | exit code | expected |\n|---|---|---|" (Spawn 0)
}
print : Stream.Writable Bytes -> String -> Msg -> Cmd Msg
print stdout line next =
Stream.writeLineAsBytes line stdout |> Task.attempt (\_ -> next)
update msg model =
when msg is
Spawn i ->
{ model = model
, command =
when Array.get i rows is
Just r ->
ChildProcess.spawn model.cp r.program r.arguments
{ shell = r.shell
, workingDirectory = ChildProcess.InheritWorkingDirectory
, environmentVariables = ChildProcess.InheritEnvironmentVariables
, runDuration = ChildProcess.NoLimit
, connection = ChildProcess.Ignored (\_ -> Started)
, onExit = \code -> Exited { row = i, code = code }
}
Nothing ->
Cmd.none
}
Exited { row = i, code } ->
{ model = model
, command =
when Array.get i rows is
Just r ->
print model.stdout ("| " ++ r.label ++ " | " ++ String.fromInt code ++ " | 0 |") (Spawn (i + 1))
Nothing ->
Cmd.none
}
Started ->
{ model = model, command = Cmd.none }
Output:
$ node app
| spawn | exit code | expected |
|---|---|---|
| `DefaultShell`, `test 1 -eq 1` | 0 | 0 |
| `NoShell`, `true` | 0 | 0 |
node:events:497
throw er; // Unhandled 'error' event
^
Error: spawn test 1 -eq 1 ENOENT
at ChildProcess._handle.onexit (node:internal/child_process:285:19)
at onErrorNT (node:internal/child_process:483:16)
at process.processTicksAndRejections (node:internal/process/task_queues:89:21)
Emitted 'error' event on ChildProcess instance at:
at ChildProcess._handle.onexit (node:internal/child_process:291:12)
at onErrorNT (node:internal/child_process:483:16)
at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
errno: -2,
code: 'ENOENT',
syscall: 'spawn test 1 -eq 1',
path: 'test 1 -eq 1',
spawnargs: []
}
Node.js v22.23.2
Cause
Gren/Kernel/ChildProcess.js. Since 6833e85 ("Fix deprecation warning when
spawning child processes") the program and its arguments are joined into one
string whatever the shell option is:
var cmd = [options.__$program].concat(options.__$arguments).join(" ");
var subproc = childProcess.spawn(cmd, {
// ...
shell: _ChildProcess_handleShell(shell),
A shell splits that string again; without one, node treats the whole string as
the file to run.
- 主要言語
- JavaScript
- スター
- 13
- フォーク
- 6
- 平均マージ
- 4日 12時間
- マージ済み PR(30日)
- 3
環境構築
このプロジェクトの環境構築ファイルはまだ確認していません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
gren-lang/node のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
似ている issue
-
Complexity: Small P-Feature: Projects page ready for merge team role: back end/devOps role: front end size: 0.25pt
難易度 1/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 67/100
bellingcat/toolkit#905 ·
-
self-care self-care:docs-build-time-investigator
難易度 2/5 半日 初心者へのやさしさ 76/100
githubnext/gh-aw-cao#14191 ·
メンテナーはふだん 1 日以内に返信
-
effort:low impact:medium RAG status: auto-triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
mastra-ai/mastra#25229 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
sugarlabs/musicblocks#8984 ·
メンテナーはふだん 1 日以内に返信