10

I have a bash script that takes a name and a command as arguments. Its pretty simple like this,

#myscript
echo $1
$2

And I run this like this

bash myscripts myjob ls

and it will echo the 'myjob' and run the ls command. But when the command is multi-word, I have to provide it with an inverted commas, like this

bash myscripts myjob "ls -l"

Now my question is, is there a way to write the shell script so that, I don't have to provide the inverted commas? Like, take everything as my command instead of the first argument? Is it possible to do with bash?

1
  • This is related to How can we run a command stored in a variable?, except that here, the arguments to the shell ("$@") already contain the command to run as separate words so where to put them is not the problem. But you can modify and use the list as in that other question.
    – ilkkachu
    Dec 10, 2021 at 15:18

1 Answer 1

13

Yes, you may use shift to shift previous arguments:

#!/bin/bash
echo "$1"
shift 1
"$@"

shift N will shift the counter so that arguments 1 to N are skipped and argument N+1 is now 1, N+2 is 2, and so on.

Note that this implies that your first command (myjob) is a single-word one and only the second command (ls -l) may be multiple-word.

4
  • 3
    That $* should be "$@" - otherwise if any of the args is a quoted string containing IFS characters, bash will word split it. e.g. if the 2nd and subsequent are are cp "filename with spaces.txt" "newfile.txt", it will become cp filename with spaces.txt newfile.txt (i.e. there will be four filename args, not two...three source filenames and one target: filename, with, spaces.txt, and newfile.txt). and there'll be even worse problems if any of the args contain shell meta-characters like ; or &.
    – cas
    Dec 10, 2021 at 14:31
  • @cas Correct and corrected. TY. Detailed reference
    – FelixJN
    Dec 10, 2021 at 14:34
  • @cas, syntax characters like ;&() shouldn't be an issue when expanding $*, even if it's unquoted. Just IFS characters and glob characters. set -- 'foo;' bar; echo $* works ok and prints foo; bar, but set -- foo "*" bar; echo $* expands the * as a glob. But yes, it should be "$@" here, and even when one needs $*, it should probably be "$*" too.
    – ilkkachu
    Dec 10, 2021 at 15:21
  • true, i was thinking of eval.
    – cas
    Dec 10, 2021 at 15:24

You must log in to answer this question.

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