-1

I am trying build a command using xargs to pass configuration parameters : user.name and user.email to git commit.

Command to be built by xargs :

git -c user.name=abc -c user.email=abc@mail.com commit

What I have tried :

echo "-c user.name=abc -c user.email=abc@mail.com" | xargs -I % git % commit

However, git returns this :

unknown option: -c user.name=abc -c user.email=abc@mail.com

Even with xargs verbose, the command works fine.

echo "-c user.name=abc -c user.email=abc@mail.com" | xargs -tI % git % commit

This prints the command to be executed git -c user.name=abc -c user.email=abc@mail.com commit which works when copy-pasted to the terminal.

Note that the configuration parameters are separated by whitespaces.

Some context for what exactly I am trying to do by passing configuration parameters

Saurabh P Bhandari
  • 6,014
  • 1
  • 19
  • 50
  • 1
    Which OS? `-J` instead of `-I` solves it for OS X. (The problem is that `-I %` replaces `%` with the line _as one parameter_ (as if you wrote `git "-c user.name=abc -c user.email=abc@mail.com" commit`). On Linux (whose `xargs` doesn't support `-J`) you can do it using a subshell: `xargs -I % bash -c "git % commit"` – Amadan Dec 11 '19 at 03:04
  • @Amadan, I have tried it on both linux shell and git-bash for windows. Shouldn't verbose for ```xargs``` show this ```git "-c user.name=abc -c user.email=abc@mail.com" commit``` instead of this ```git -c user.name=abc -c user.email=abc@mail.com commit``` ? (based on the problem described for ```-I```) – Saurabh P Bhandari Dec 11 '19 at 03:17
  • 2
    No. I said "as if". `xargs` doesn't actually construct quotes; it executes the function using a C function similar to this: `execl("git", "-c user.name=abc -c user.emal=abc@mail.com", "commit")`, where it executes the `git` command with two arguments. Splitting the command line by spaces (or taking a quoted string as one) is shell's job, but there is no shell involved here. The verbose just prints all the arguments connected with a space, just like echo would do; you can't distinguish how parameters are split. – Amadan Dec 11 '19 at 03:21

1 Answers1

1

Per comments, xargs was replacing the single parameter % with a single parameter -c user.name=abc -c user.email=abc@mail.com; the resultant command

git -c user.name=abc -c user.email=abc@mail.com commit

has two parameters, the first of which is -c user.name=abc -c user.email=abc@mail.com, clearly an invalid option.

The most portable way to solve it that I can think of is to have a shell re-interpret the line:

echo "-c user.name=abc -c user.email=abc@mail.com" | xargs -I % bash -c "git % commit"

This way, xargs will execute bash with two parameters: -c and git -c user.name=abc -c user.email=abc@mail.com commit. bash -c command executes that command, which includes full command line parsing that bash normally performs. This will result in bash executing git with five parameters: -c, user.name=abc, -c, user.email=abc@mail.com and commit.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • As per [this](https://www.gnu.org/software/parallel/parallel_alternatives.html#DIFFERENCES-BETWEEN-xargs-AND-GNU-Parallel), ```If you use a replace string in xargs (-I) you can not force xargs to use more than one argument.``` – Saurabh P Bhandari Jan 09 '20 at 06:29
  • 1
    I wanted to confirm with the docs too, +1 and accepted the answer :) – Saurabh P Bhandari Jan 09 '20 at 07:01