0

I'm writing a bash script that runs everything passed to it. I want it to work like so:

$ ./myscript.sh echo hello world
# should run 'echo hello world'

This is my script thus far:

#!/bin/bash

eval "$@"

This works fine with the above example:

$ ./myscript.sh echo hello world
# successfully runs `echo hello world`

But if any of the passed arguments have spaces, it doesn't work correctly, because the spaces get broken up into multiple arguments:

$ ./myscript.sh sh -c 'echo hello world'
# runs `sh -c 'echo' 'hello' 'world'` instead of `sh -c 'echo hello world'`, so nothing is printed

How can I pass all the arguments a bash script receives to eval without interpreting the spaces in them at all?

1
  • 3
    Why do you need the eval? Just "$@" should work fine for the examples shown.
    – muru
    Commented May 13, 2021 at 5:13

1 Answer 1

6

What good does eval give you in this case? Use this:

"$@"

i.e. eval "$@".

If you still think you need eval then this:

eval "${@@Q}"

${var@Q} makes Bash quote and/or escape the content, so after being parsed again (and this is what eval does) it comes to its original state. ${var@Q} is helpful if the content must be parsed (e.g. you pass it via ssh to a remote shell you cannot avoid). If you can avoid extra parsing then do avoid. In your case you do this by not using eval.

This answer notices @Q in Bash is not perfect.

1
  • Thanks! I didn't know I could just put "$@" on a line by itself.
    – Suchipi
    Commented May 13, 2021 at 10:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .