0

I have this script which I am writing to help my team squash Git commits into the integration branch on the remote. Needless to say my bash scripting is a bit wanting.

First, here is the script:

    #!/usr/bin/env bash

    FEATURE_BRANCH_NAME="$1" &&


    if [ -z "$1" ]; then
      echo "You did not specify a branch name."
      exit 1;
    fi

    if [${1} == "--force"]; then     # the problem seems to happen here!
      echo "You did not specify a branch name."
      exit 1;
    fi

    if [ "$2" != "--force" ]; then
      echo "Are you sure you want to squash commits for branch name = $FEATURE_BRANCH_NAME? If so use --force."
      exit 1;
    fi



    git fetch origin &&
    git checkout -b temp_branch origin/integration &&
    git merge -Xtheirs --squash -m "squashed with branch=$FEATURE_BRANCH_NAME" $FEATURE_BRANCH_NAME &&
    git checkout $FEATURE_BRANCH_NAME &&
    git merge temp_branch &&
    git push origin $FEATURE_BRANCH_NAME


    #end

The problem I am seeing is that if I execute the above script like so:

./script.sh $(git rev-parse --abbrev-ref HEAD)

then bash tries to actually execute the command represented by the value of $(git rev-parse --abbrev-ref HEAD), (which is the current branch name).

So in other words, if the output of $(git rev-parse --abbrev-ref HEAD) is "xyz_branch", then bash will try to run $ xyz_branch, and bash will spit out:

[xyz_branch: command not found

Above the in script there is a comment # which specifies which line this happening on. What the heck is going on?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 2
    You're missing a space between `[` and `${1}`. – larsks Nov 02 '16 at 00:13
  • 3
    http://shellcheck.net/ is your friend. – Charles Duffy Nov 02 '16 at 00:16
  • ...in terms of how to think about it: `[` is a **command**. There's actually a `/usr/bin/[` (or `/bin/[`, depending on your OS) on-disk, though most shells also provide a built-in version for performance reasons as well. As such, like any other command, you need spaces between the command name and its arguments. You can't run `lsmydir/` instead of `ls mydir/`; the same is true of `[`. – Charles Duffy Nov 02 '16 at 00:21
  • @CharlesDuffy awesome tool! – Shahbaz Nov 02 '16 at 00:24

1 Answers1

5

The problem is that you are missing a space here:

if [ ${1} == "--force" ];
    ^                 ^ (second error)

Also, you probably mean to use = instead of ==.


The if construct in bash has a syntax like this:

if command; ...

And the result of command tells if whether to execute the if or the else part. Now [ is another command (otherwise known as test).

So, in bash, if you write:

$ [ a = b ]

This is actually the program [ called with arguments a, =, b and ] (the program could be internally handled by bash, even if you actually have an executable named [)

Looking back at your problem, you are trying to execute:

$ [${1} == "--force"]

which is the program [${1} with parameters == and --force]. Clearly not what you want!


A couple of other things to bare in mind here. First, it's a good idea to quote "${1}" because if it has spaces or is empty, as you might imagine it would create an incorrect list of arguments to [.

Another is that you don't have to always use [ in the context of an if, while etc. You can for example take advantage of the C-like short-circuit property of logical operations:

$ [ "$a" = "$b" ] && echo My variables are equal
Shahbaz
  • 46,337
  • 19
  • 116
  • 182