Skip to content

Commit 52a7a0d

Browse files
committed
src: support "--" after "-e" as end-of-options
When the double dash "--" appears after "-e <script>" on the command line, it indicates the end of options and the beginning of positional parameters for the script.
1 parent 15df5c0 commit 52a7a0d

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

doc/api/cli.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ To view this documentation as a manual page in your terminal, run `man node`.
1010

1111
## Synopsis
1212

13-
`node [options] [v8 options] [script.js | -e "script"] [arguments]`
13+
`node [options] [v8 options] [script.js | -e "script"] [--] [arguments]`
1414

1515
`node debug [script.js | -e "script" | <host>:<port>] …`
1616

@@ -251,6 +251,15 @@ added: v0.11.15
251251

252252
Specify ICU data load path. (overrides `NODE_ICU_DATA`)
253253

254+
### `--`
255+
<!-- YAML
256+
added: REPLACEME
257+
-->
258+
259+
Indicate the end of node options. Pass the rest of the arguments to the script.
260+
If no script filename or eval/print script is supplied prior to this, then
261+
the next argument will be used as a script filename.
262+
254263
## Environment Variables
255264

256265
### `NODE_DEBUG=module[,…]`

doc/node.1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ node \- Server-side JavaScript runtime
3737
.RI [ script.js \ |
3838
.B -e
3939
.RI \&" script \&"]
40+
.B [--]
4041
.RI [ arguments ]
4142
.br
4243
.B node debug
@@ -175,6 +176,13 @@ used to enable FIPS-compliant crypto if Node.js is built with
175176
.BR \-\-icu\-data\-dir =\fIfile\fR
176177
Specify ICU data load path. (overrides \fBNODE_ICU_DATA\fR)
177178

179+
.TP
180+
.BR \-\-\fR
181+
Indicate the end of node options. Pass the rest of the arguments to the script.
182+
183+
If no script filename or eval/print script is supplied prior to this, then
184+
the next argument will be used as a script filename.
185+
178186
.SH ENVIRONMENT VARIABLES
179187

180188
.TP

src/node.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3853,6 +3853,9 @@ static void ParseArgs(int* argc,
38533853
} else if (strcmp(arg, "--expose-internals") == 0 ||
38543854
strcmp(arg, "--expose_internals") == 0) {
38553855
// consumed in js
3856+
} else if (strcmp(arg, "--") == 0) {
3857+
index += 1;
3858+
break;
38563859
} else {
38573860
// V8 option. Pass through as-is.
38583861
new_v8_argv[new_v8_argc] = arg;

test/parallel/test-cli-eval.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ const child = require('child_process');
1111
const path = require('path');
1212
const nodejs = '"' + process.execPath + '"';
1313

14+
if (process.argv.length > 2) {
15+
console.log(process.argv.slice(2).join(' '));
16+
process.exit(0);
17+
}
1418

1519
// replace \ by / because windows uses backslashes in paths, but they're still
1620
// interpreted as the escape character when put between quotes.
@@ -113,3 +117,38 @@ child.exec(nodejs + ` -e 'require("child_process").fork("${emptyFile}")'`,
113117
assert.strictEqual(proc.stderr, '');
114118
assert.strictEqual(proc.stdout, 'start\nbeforeExit\nexit\n');
115119
}
120+
121+
[ '-arg1',
122+
'-arg1 arg2 --arg3',
123+
'--',
124+
'arg1 -- arg2',
125+
].forEach(function(args) {
126+
127+
// Ensure that arguments are successfully passed to eval.
128+
const opt = ' --eval "console.log(process.argv.slice(1).join(\' \'))"';
129+
const cmd = `${nodejs}${opt} -- ${args}`;
130+
child.exec(cmd, common.mustCall(function(err, stdout, stderr) {
131+
assert.strictEqual(stdout, args + '\n');
132+
assert.strictEqual(stderr, '');
133+
assert.strictEqual(err, null);
134+
}));
135+
136+
// Ensure that arguments are successfully passed to print.
137+
const popt = ' --print "process.argv.slice(1).join(\' \')"';
138+
const pcmd = `${nodejs}${popt} -- ${args}`;
139+
child.exec(pcmd, common.mustCall(function(err, stdout, stderr) {
140+
assert.strictEqual(stdout, args + '\n');
141+
assert.strictEqual(stderr, '');
142+
assert.strictEqual(err, null);
143+
}));
144+
145+
// Ensure that arguments are successfully passed to a script.
146+
// The first argument after '--' should be interpreted as a script
147+
// filename.
148+
const filecmd = `${nodejs} -- ${__filename} ${args}`;
149+
child.exec(filecmd, common.mustCall(function(err, stdout, stderr) {
150+
assert.strictEqual(stdout, args + '\n');
151+
assert.strictEqual(stderr, '');
152+
assert.strictEqual(err, null);
153+
}));
154+
});

0 commit comments

Comments
 (0)