1

I am working on a simple bash script to add some extra functionality to git status. Currently, I'm doing this by adding the following script (named git) to my path:

#!/bin/bash

# Simple script to automatically configure user info between multiple repositories
#  by overloading the functionality of 'git status'
if [[ "$1" == "status" ]]; then
    # do something extra, then run vanilla 'git status'
    /usr/bin/git status
else
    # behave normally
    /usr/bin/git $@
fi

When I enter git <any args>, Bash finds my script named git first, so it runs that. The problem I'm having is with the else clause. Apparently, running /usr/bin/git $@ within a script like this is not the same as running it from the command line. For example, when I run git commit:

$ git commit -m "Init HW4 Rust project" # runs the else branch of my script
error: pathspec 'HW4' did not match any file(s) known to git
error: pathspec 'Rust' did not match any file(s) known to git
error: pathspec 'project' did not match any file(s) known to git
$ /usr/bin/git commit -m "Init HW4 Rust project" # runs my standard git installation
On branch main
Your branch is ahead of 'origin/main' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

I suspect this has to do with the $@ variable. $@, as I understand it, represents all command line arguments received by a Bash script, except for the 0th one (the command). How is this any different from typing out the arguments explicitly?

Robbie
  • 107
  • 3
  • 3
    It looks like you forgot to properly quote `"$@"`. – Toby Speight Apr 05 '23 at 14:58
  • 2
    it's a common bash gotcha: if you use `$@` instead of `"$@"`, the arguments with spaces in them (as in: `"Init HW4 Rust project"`) will get split into several arguments. In your example, your command becomes `git commit -m Init HW4 Rust project` (4 separate arguments after `-m`). – LeGEC Apr 05 '23 at 15:00
  • In other words, your quotes are getting stripped from the input. – Jardel Lucca Apr 05 '23 at 15:03
  • https://stackoverflow.com/search?q=%5Bbash%5D+pass+all+parameters – phd Apr 05 '23 at 15:06

1 Answers1

1

Because you didn't quote $@, you got more arguments than you intended:

$ set -- commit -m "Init HW4 Rust project"
$ printf '%q\n' $@
commit
-m
Init
HW4
Rust
project

Compare that to properly quoted "$@":

$ printf '%q\n' "$@"
commit
-m
Init\ HW4\ Rust\ project
Toby Speight
  • 27,591
  • 48
  • 66
  • 103