I read a similar example from bash programming book:

$ cat indirection 
#!/usr/bin/env bash

set -x
eval "${!num#*:}"

When I execute the script with bash indirection "test:echo blah", then how is the last line of the script processed? I guess first the indirection happens so that eval "${!num#*:}" becomes eval "${1#*:}"? Then substring removal takes place and eval "${1#*:}" becomes eval echo blah? If yes, then why is eval needed, i.e ${!num#*:} instead of eval "${!num#*:}" would provide the same results?

  • Does unix.stackexchange.com/a/164733/117549 help?
    – Jeff Schaller
    Commented Jul 6, 2017 at 0:13
  • @JeffSchaller Sorry but Brace expansion is not what this question is about.
    – user232326
    Commented Jul 6, 2017 at 1:50
  • I am assuming that num=1 is in fact num=$1 according to your execute string.
    – user232326
    Commented Jul 6, 2017 at 2:31

1 Answer 1


The output of the parameter expansion is:

$ echo "${1#*:}"
echo blah

Well, yes, in this specific case:

$ set -- "test:echo blah"
$ eval "${1#*:}"

$ ${1#*:}

Execute the same command. But that is not always true:

$ "${1#*:}"
bash: echo blah: command not found

In fact, an string that contains shell meta characters will not work correctly even if unquoted.

$ set -- "test:echo blah > file"
blah > file

The redirection did not happen, but (beware that a file will be created):

$ eval "${1#*:}"

Will create a file called file in the PWD.

You must log in to answer this question.

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