16

So I have a bash script that is generating a string of commands that I want to be run. The output looks something like

$ program "command1 command2 ... commandN"

But the program is interpreting (as it should) "command1 command2 ... commandN" as one argument.

Is there away to turn pass the string into the argument as split arguments so the program would interpret each command as an individual argument?

$ program command1 command2 ... commandN

Thanks for any help.

Jim Fell
  • 13,750
  • 36
  • 127
  • 202
trev9065
  • 3,371
  • 4
  • 30
  • 45

3 Answers3

21

I've done this, implementing your scenario : The idea is to use "a b c" as argument for cat

$ echo a > a
$ echo b > b
$ echo c > c
$ args="a b c"

Trying "a b c" as "one argument"

$ cat $args
cat: a b c: No such file or directory

Workaround to separate arguments :

$ cat $(echo $args)
a
b
c

Hope it helps you

(So you should run program $(echo "command1 command2 ... commandN")

Blusky
  • 3,470
  • 1
  • 19
  • 35
  • 8
    This is not safe for arguments that can themselves contain spaces and/or which contain shell metacharacters. The correct way to do this is to use an array or arguments and not a string see [Bash FAQ 0050](http://mywiki.wooledge.org/BashFAQ/050) for more details. – Etan Reisner May 05 '15 at 19:53
  • This works with shell, which makes me happy. Thank you – Bogdans Nov 23 '21 at 15:23
  • Hmmm, in my environment it is not the case. `cat $args` output `a`, `b`, `c`. It splits $args, but not "$args". – YouJiacheng Feb 20 '23 at 03:48
  • You maybe used an custom `IFS`, but `$(echo $args)` should not work either in such case. – YouJiacheng Feb 20 '23 at 04:26
2

You can rely on Bash's Word Splitting.

root@036717c8f088:/# x="a b c";cat $x
cat: a: No such file or directory
cat: b: No such file or directory
cat: c: No such file or directory

The only thing you need to do is NOT adding double quotes.

root@036717c8f088:/# x="a b c";cat "$x"
cat: 'a b c': No such file or directory

If you don't want to define a variable, you can use expr:

root@036717c8f088:/# cat $(expr "a b c")
cat: a: No such file or directory
cat: b: No such file or directory
cat: c: No such file or directory

Thus, the answer can be:

program $(expr "command1 command2 ... commandN")

If the word splitting doesn't work, it might be caused by IFS, you can unset IFS.

YouJiacheng
  • 449
  • 3
  • 11
0

I love the xargs command which takes your quoted string as input and runs the program. For feeding xargs you use the pipe "|"

A dummy "program.sh":

$ cat program.sh
#!/bin/bash
echo "This is my 1st argument: $1"
echo "This is my 2nd argument: $2"
echo "This is my 3rd argument: $3"

$ ARGS='command1 command2 command3'
$ echo "$ARGS" | xargs ./program.sh
This is my 1st argument: command1
This is my 2nd argument: command2
This is my 3rd argument: command3

Note that $ARGS has been quoted explicitely. The main advantage of this method is that xargs has plenty of options.

alelorca
  • 99
  • 1
  • 3