Git bashshell脚本错误sh:[:缺少`]';

Git bashshell脚本错误sh:[:缺少`]';,git,bash,shell,unix,bitbucket,Git,Bash,Shell,Unix,Bitbucket,目标: 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://git@bitbucket.org/$2/$3" # Use github if spec

目标:

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://git@bitbucket.org/$2/$3"

 # Use github if specified
 if [ "$1" == "gh" ]; then
      API="https://api.github.com/user/repos"
      DATA='{"name":"$3", "description": "$4"}'
      REMOTE="git@github.com:$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
}
username@COMPUTER-NAME /path/to/local/repo
$ initg gh username bash_test desc
sh: [: missing `]'
sh: [: missing `]'
Enter host password for user 'username':
我正在尝试创建一个有用的快捷方式,用于在本地初始化git repo,同时在bitbucket或github上创建远程repo源。此函数被添加到我的主目录中的my
.bashrc
文件中

下面是bash函数(产生错误):

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://git@bitbucket.org/$2/$3"

 # Use github if specified
 if [ "$1" == "gh" ]; then
      API="https://api.github.com/user/repos"
      DATA='{"name":"$3", "description": "$4"}'
      REMOTE="git@github.com:$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
}
username@COMPUTER-NAME /path/to/local/repo
$ initg gh username bash_test desc
sh: [: missing `]'
sh: [: missing `]'
Enter host password for user 'username':
错误:

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://git@bitbucket.org/$2/$3"

 # Use github if specified
 if [ "$1" == "gh" ]; then
      API="https://api.github.com/user/repos"
      DATA='{"name":"$3", "description": "$4"}'
      REMOTE="git@github.com:$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
}
username@COMPUTER-NAME /path/to/local/repo
$ initg gh username bash_test desc
sh: [: missing `]'
sh: [: missing `]'
Enter host password for user 'username':
我的问题:

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://git@bitbucket.org/$2/$3"

 # Use github if specified
 if [ "$1" == "gh" ]; then
      API="https://api.github.com/user/repos"
      DATA='{"name":"$3", "description": "$4"}'
      REMOTE="git@github.com:$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
}
username@COMPUTER-NAME /path/to/local/repo
$ initg gh username bash_test desc
sh: [: missing `]'
sh: [: missing `]'
Enter host password for user 'username':
首先,我的错误在哪里?其次,如何改进此脚本的控制流或结构以实现所述目标?

Update/Temporary Response 好吧,严格来说,这不是一个(知情的)答案,但是我已经设法解决了这个问题

调试

我在一个单独的专用脚本文件中运行了函数和命令,使用devnull在原始帖子的评论中建议的命令
bash-x test.sh

这在shell中产生了相当多的反馈。在我放弃之前,我认为这是最关键的反馈

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://git@bitbucket.org/username/bash_test
+ '[' gh == gh ']'
+ API=https://api.github.com/user/repos
+ DATA='{"name":"$3", "description": "$4"}'
+ REMOTE=git@github.com:username/bash_test
+ '[' -z https://api.github.com/user/repos ']'
+ '[' -z '{"name":"$3", "description": "$4"}' ']'
+ '[' -z git@github.com: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':
问题:

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://git@bitbucket.org/$2/$3"

 # Use github if specified
 if [ "$1" == "gh" ]; then
      API="https://api.github.com/user/repos"
      DATA='{"name":"$3", "description": "$4"}'
      REMOTE="git@github.com:$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
}
username@COMPUTER-NAME /path/to/local/repo
$ initg gh username bash_test desc
sh: [: missing `]'
sh: [: missing `]'
Enter host password for user 'username':

因此,问题似乎在于设置数据的变量表达式(如下所示)。首先,
$3
$4
引用的传递给脚本的参数不能插入到单个带引号的字符串中

DATA='{"name":"$3", "description": "$4"}'
此外,逗号和第二个分号后面的空格奇怪地用单引号括起来,将字符串分成几段,这在最终失败的curl调用中可见

分辨率

因此,除了使用
[[]]
双方括号而不是原始的单方括号外,我只是用大括号(如
${3}
)包装每个插值变量,并修复了数据变量赋值中引号和空格的使用(如下所示):

后期脚本


我认为这个答案是可以改进的,如果有人能够扩展这个答案,那就太好了。我不明白为什么curl调用中使用的
$DATA
变量解析为
'{“name”:“$3”,“description”:“$4”}”
若要输入
数据
变量,请尝试以下操作:

printf -vDATA '{"name":"%s", "description": "%s"}' $3 $4
echo "$DATA"

我曾多次遇到bash的这种胡说八道(一个bug?),解决方法是用
测试某个条件来替换
[某个条件]
我遇到了这种错误,因为我以前没有使用空格]例如:

if [ "$#" -ne 2]; then
而不是

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

PS:我知道这是一个老问题,但它可能会对某些人有所帮助:)

尝试
bash-x initg gh username bash_test desc
,查看哪些行触发了错误。并使用
[[]]
语法,而不是
[]
(例如)它所说的
sh:
似乎意味着它运行在
sh
的适当变体中,或者在POSIX兼容模式下运行
bash
,这可能会加剧问题。此外,它是一个函数,因此虽然上面的代码看起来不错,但实际上您可能调用了错误的函数,因为它已经是sourcedTry了,将上面的代码和触发函数的命令放在一个单独的文件中,当设置
$1
等于“gh”时,
$3
$4
的值时,当
$1
等于“gh”时,说
test.sh
并调用
bash-x test.sh
不会展开,因为它们出现在单引号中。当您以后在调用
curl
时使用
$DATA
unquoted,或者可能(由于
[
-相关错误)将其与
-z
一起使用时,这可能会导致问题。正如您已经编写的那样,使用“和”进行引用“工作方式不同。有关确切的详细信息,请查看'man bash',部分引用。最重要的部分是,$substitutions不会发生在'.IMHO,DATA='{“name”:“$3'”,description:“$4'}”看起来更好一些:)