@@ -270,15 +270,25 @@ func (d *Devbox) RunScript(ctx context.Context, envOpts devopt.EnvOptions, cmdNa
270270 // better alternative since devbox run and devbox shell are not the same.
271271 env ["DEVBOX_SHELL_ENABLED" ] = "1"
272272
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"
274283 for idx , arg := range cmdArgs {
275284 cmdArgs [idx ] = strconv .Quote (arg )
276285 }
277286
278287 var cmdWithArgs []string
279288 if _ , ok := d .cfg .Scripts ()[cmdName ]; ok {
280289 // 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 ... )
282292 } else {
283293 // Arbitrary commands should also run the hooks, so we write them to a file as well. However, if the
284294 // 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
293303 if err != nil {
294304 return err
295305 }
296- cmdWithArgs = []string {shellgen .ScriptPath (d .ProjectDir (), arbitraryCmdFilename )}
306+ script := shellgen .ScriptPath (d .ProjectDir (), arbitraryCmdFilename )
307+ cmdWithArgs = []string {strconv .Quote (script )}
297308 env ["DEVBOX_RUN_CMD" ] = strings .Join (append ([]string {cmdName }, cmdArgs ... ), " " )
298309 }
299310
0 commit comments