Bash shell script error sh: [: missing `]'

26,142

Solution 1

I've got that kind of error because I didn't use space before ] ex:

if [ "$#" -ne 2]; then

instead of

if [ "$#" -ne 2 ]; then

PS: I know this is an old question but it might do some help for someone :)

Solution 2

I've run into such nonsense from bash several times (a bug?), and the way out was to replace [ some-condition ] by test some-condition

Solution 3

Update/Provisional Answer

Okay this is strictly speaking not an (informed) answer, however I have managed to resolve the issue.

Debugging

I ran the function and command in a separate dedicated script file, using the command bash -x test.shsuggested by devnull in the comments of the original post.

This yielded quite a lot of feedback in the shell. Here is what I believe to be the most critical feedback, before I aborted it.

username@COMPUTERNAME /d/test
$ bash -x test.sh
+ initg gh username bash_test desc
+ local API=https://api.bitbucket.org/1.0/repositories/
+ local 'DATA=name=bash_test&description=desc&is_private=true&scm=git'
+ local REMOTE=ssh://[email protected]/username/bash_test
+ '[' gh == gh ']'
+ API=https://api.github.com/user/repos
+ DATA='{"name":"$3", "description": "$4"}'
+ [email protected]:username/bash_test
+ '[' -z https://api.github.com/user/repos ']'
+ '[' -z '{"name":"$3", "description": "$4"}' ']'
+ '[' -z [email protected]:username/bash_test ']'
+ '[' -z username ']'
+ curl -X POST -u username https://api.github.com/user/repos -d '{"name":"$3",' '"description":' '"$4"}'
+ Enter host password for user 'username':

The Issue:

So the issue seems to lie with the variable expression (below) where DATA is set. Firstly the arguments passed to the script, referenced by $3 and $4 cannot be interpolated within a single quoted string.

DATA='{"name":"$3", "description": "$4"}'

Also the spaces after the comma and second semi-colon strangely wrapped in single quotes breaking the string in several pieces, visible in the resulting failed curl call.

Resolution

So apart from using [[ ]] double square brackets instead of the original singular square brackets, I simply wrapped each interpolated variable with curly braces such as ${3} and fixed the use of quotes and spaces in the DATA variable assignment (below):

DATA="{\"name\":\"${3}\",\"description\":\"${4}\"}"

Post script

I this answer can be improved, if anyone can extend on this answer that would be great. I'm confused as to why the $DATA variable used in the curl call resolved to '{"name":"$3",' '"description":' '"$4"}'

Share:
26,142
cjross
Author by

cjross

Updated on July 16, 2022

Comments

  • cjross
    cjross almost 2 years

    Aim:

    I'm trying to create a useful shortcut for initializing a git repo locally, and simultaneously creating a remote repo origin on bitbucket or github. This function is added to my .bashrc file in my home directory.

    Here is the bash function (which yields an error):

    function initg() {
     # Defaults to bitbucket API
     local API="https://api.bitbucket.org/1.0/repositories/"
     local DATA="name=$3&description=$4&is_private=true&scm=git"
     local REMOTE="ssh://[email protected]/$2/$3"
    
     # Use github if specified
     if [ "$1" == "gh" ]; then
          API="https://api.github.com/user/repos"
          DATA='{"name":"$3", "description": "$4"}'
          REMOTE="[email protected]:$2/$3"
     fi
    
     if [ -z "$API" ] || [ -z "$DATA" ] || [ -z "$REMOTE" ] || [ -z "$2" ]
     then
          echo "A parameter is missing or incorrect"
     else
          curl -X POST -u $2 ${API} -d ${DATA}
          git init
          git add .
          git commit -m "Created repo"
          git remote add origin $REMOTE
          git push -u origin master
     fi
    }
    

    The error:

    username@COMPUTER-NAME /path/to/local/repo
    $ initg gh username bash_test desc
    sh: [: missing `]'
    sh: [: missing `]'
    Enter host password for user 'username':
    

    My Question:

    First, where is my error? Secondly, how might I improve the control flow or structure of this script to achieve the stated goals?