@@ -270,15 +270,25 @@ func (d *Devbox) RunScript(ctx context.Context, envOpts devopt.EnvOptions, cmdNa
270
270
// better alternative since devbox run and devbox shell are not the same.
271
271
env ["DEVBOX_SHELL_ENABLED" ] = "1"
272
272
273
- // wrap the arg in double-quotes, and escape any double-quotes inside it
273
+ // wrap the arg in double-quotes, and escape any double-quotes inside it.
274
+ //
275
+ // TODO(gcurtis): this breaks quote-removal in parameter expansion,
276
+ // command substitution, and arithmetic expansion:
277
+ //
278
+ // $ unset x
279
+ // $ echo ${x:-"my file"}
280
+ // my file
281
+ // $ devbox run -- echo '${x:-"my file"}'
282
+ // "my file"
274
283
for idx , arg := range cmdArgs {
275
284
cmdArgs [idx ] = strconv .Quote (arg )
276
285
}
277
286
278
287
var cmdWithArgs []string
279
288
if _ , ok := d .cfg .Scripts ()[cmdName ]; ok {
280
289
// it's a script, so replace the command with the script file's path.
281
- cmdWithArgs = append ([]string {shellgen .ScriptPath (d .ProjectDir (), cmdName )}, cmdArgs ... )
290
+ script := shellgen .ScriptPath (d .ProjectDir (), cmdName )
291
+ cmdWithArgs = append ([]string {strconv .Quote (script )}, cmdArgs ... )
282
292
} else {
283
293
// Arbitrary commands should also run the hooks, so we write them to a file as well. However, if the
284
294
// command args include env variable evaluations, then they'll be evaluated _before_ the hooks run,
@@ -293,7 +303,8 @@ func (d *Devbox) RunScript(ctx context.Context, envOpts devopt.EnvOptions, cmdNa
293
303
if err != nil {
294
304
return err
295
305
}
296
- cmdWithArgs = []string {shellgen .ScriptPath (d .ProjectDir (), arbitraryCmdFilename )}
306
+ script := shellgen .ScriptPath (d .ProjectDir (), arbitraryCmdFilename )
307
+ cmdWithArgs = []string {strconv .Quote (script )}
297
308
env ["DEVBOX_RUN_CMD" ] = strings .Join (append ([]string {cmdName }, cmdArgs ... ), " " )
298
309
}
299
310
0 commit comments