2

Using this post as a starting point I am running the following in bash:

seq 1 5 | xargs -d $'\n' sh -c 'for arg do echo $arg; done'

Expected output

1
2
3
4
5

Actual output

2
3
4
5

i.e. is missing the first of the intended arguments.

Am probably being a tool, but wondering why this is.

user2567544
  • 376
  • 1
  • 12
  • That dupe question has no mention of `xargs` so how it is an exact dupe? – anubhava Jan 12 '21 at 18:20
  • @anubhava You have a golden badge, you can reopen the question unilaterally if you didn't like the duplicate target, or add a better one. I don't think this question is really related to xargs though – oguz ismail Jan 12 '21 at 18:34
  • I don't disagree that linked answer is related to this problem but here OP is asking `Using xargs to run multiple commands` and we already have an answer taking out `sh -c` from a proposed solution – anubhava Jan 12 '21 at 18:39
  • 1
    @anubhava Well, go ahead and reopen it then – oguz ismail Jan 12 '21 at 18:44

3 Answers3

2

You have to pass some dummy value at position 0 to sh script like this:

seq 1 5 | xargs -d $'\n' sh -c 'for arg do echo $arg; done' _
1
2
3
4
5

Without passing _ to sh script 1 is passed as $0 whereas for arg loops through positional arguments starting with position 1 only.

anubhava
  • 761,203
  • 64
  • 569
  • 643
2

In conclusion, do you want to list number or execute command by row? Usually, use below command in bash.

seq 1 5 | xargs -n 1 -I {} echo {}

Output

1
2
3
4
5
0

The problem lies with your inline bash code.

seq 1 5 | xargs -n echo produces the desired result. It can also be simplified to seq 5 | xargs -n echo because seq assumes the range starts at 1.

J Iguadeza
  • 77
  • 7