0

I want to pass tokens a b c as arguments of a script that will output a - b - c. If I have a script dummy.sh that does echo "$1 - $2 - $3" and a dummy.dat file containing :

a b c
d e f

and I want to output

a - b - c
d - e - f

I can do something like :

cat dummy.dat | xargs -Iline sh -c "sh dummy.sh line"
cat dummy.dat | xargs -n3 sh dummy.sh

But what if I don't want a one-line script, could I just use sh -c "echo $1 - $2 - $3" but how ?

Sybuser
  • 121
  • 8

2 Answers2

1

First of all, you don't do sh -c "echo $1 - $2 - $3" because the double-quotes will cause your current shell to expand $1, $2 and $3. Even if you managed to set these in the current shell beforehand, it still wouldn't be a good general way because the result of the expansion would be interpreted by sh as shell code. Unless you want it to be interpreted as shell code, don't do this.

xargs -Iline sh -c "sh dummy.sh line" is similarly flawed: line will be interpreted by the outer sh. What if it happens to be ; rm -f /important/file or $(shutdown)? It's like embedding {}. Don't.

If you want to provide some values, provide as arguments to the sh itself:

<dummy.dat xargs -n3 sh -c 'echo "$1 - $2 - $3"' sh

The second sh is explained here: What is the second sh in sh -c 'some shell code' sh? The single-quotes protect $1, $2 and $3 from being expanded by the current shell. sh gets the shell code exactly as it is within the single-quotes: echo "$1 - $2 - $3". Arbitrary strings are passed as arguments, expanded only by sh, there is no code injection vulnerability.

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
0

I think this is it :

cat dummy.dat | xargs -n3 sh -c 'echo "$0 - $1 - $2"'
Sybuser
  • 121
  • 8
  • Almost. `$0` is not for this. See the section named "Discrepancy?" and further in [this answer of mine](https://superuser.com/a/1526230/432690). – Kamil Maciorowski Oct 01 '22 at 19:56