2

Suppose I have this in my .gitconfig alias:

testing =!"\
echo \"hi\" \
"

if I run git testing 1 4 it will echo the parameters back to me:

hi 1 4


Also if I use sh to try to get all the parameters it doesn't show the first:

testing =!sh -c 'echo "$@"'

if I run git testing 1 4 it will only show 4.


What's the reason for this?

newguy
  • 617
  • 6
  • 15

2 Answers2

2

If your sh is bash, then the Bash man page has some info:

-c string

If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.

Before you get a chance to access $@, Bash interprets the -c and will pass the subsequent arguments through as parameters to the sub shell. This means $0 will be the next value passed, which is 4 (essentially $@ and $0 are the same at this point because there is only one value).

If you run the sh with -v you will see slightly more about what is happening:

$ git testing 1 4
echo $@
4

So the echo $@ gets only 4 in its arguments. The -c will create a sub shell, and pass $@ though. Remember this contains only 4 now. This is where you are losing the 1.

Community
  • 1
  • 1
acanby
  • 2,936
  • 24
  • 26
  • 1
    Nice, I like the precise explanation of why the parameter is missing. I didn't address that in my answer. +1 – VonC Jun 18 '15 at 07:14
  • @VonC, thanks mate. Always hard to get an answer in when you're on the case :) – acanby Jun 18 '15 at 07:19
  • Why does `$@` only contain 4, though, at *any* point? At the point when Bash interprets `-c`, why is `$@` just `4` instead of `1 4`? – Kyle Strand Jun 18 '15 at 07:22
  • @acanby Thanks but I'm confused. In my first example why are the parameters echoed back to me? And in my second example as @Kyle said why is it just 4 instead of 1 4. Aren't `1` and `4` both subsequent arguments to testing? – newguy Jun 19 '15 at 20:18
  • Maybe you meant that `$@` and `$1` are the same, since `$@` should never include the 0 argument? – Kyle Strand Jun 19 '15 at 20:49
  • @acanby Hi I'd like to mark this as correct but can you please clear up the confusion first. – newguy Jul 20 '15 at 00:45
1

I just tested:

testing = !sh -c 'echo "$@"' {};

This does display all the parameters.

This is similar to "find: missing argument to -exec"

A -exec command must be terminated with a ; (so you usually need to type \; or ';' to avoid interpretation by the shell)

This would work too:

[alias]
    testing = "!f() { echo \"$@\"; }; f"
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • the semi-colon in the first example doesn't seem to make a difference, it's the braces that do though. Why is that? The second example also works. – newguy Jun 19 '15 at 20:29
  • @newguy `{}` forces the execution of the `sh -c` command in the context of the current shell instead of creating a subshell (http://stackoverflow.com/a/24048024/6309) – VonC Jun 19 '15 at 21:02