Git Bash "If" AND "For" 同一脚本中的逻辑似乎不正确

Git Bash "If" AND "For" logic in same script seems to be incorrect

我有一个循环遍历我所有 bitbucket 存储库的脚本,如果它在本地不存在,它应该克隆它,如果存在,则将其拉出。可以说我没有任何需要的目录。我可以 运行 下面的脚本,一切正常。如果我再次 运行 相同的脚本,它仍然会点击 if 语句的第一部分并说 "the destination already exists and is not an empty repository"。现在假设我摆脱了“!”,它现在触及了所有内容的逻辑的第二部分。这对我来说没有意义。我是 git bash 的新手,因此我们将不胜感激。

#!/bin/bash
#script to get all repositories under a user from bitbucket
#Usage: getAllRepos.sh [user]

curl -u user https://api.bitbucket.org/1.0/users/user > repoinfo
for repo_name in $(grep -oE '\"slug\": "[^"]*"' repoinfo | cut -f4 -d\")
do
if [ ! -d "$repo_name" ];  then

git clone "git@bitbucket.org:user/$repo_name.git" "C:\Users\user\.ssh\$repo_name"

else 

git pull "git@bitbucket.org:user/$repo_name.git"

fi
done

我已更新代码以包含来自推荐网站的更正,但它仍然无法正常工作。

#!/bin/bash
die() { echo "ERROR: $*" >&2; exit 1; }

user=${1:-Monzingo}

mkdir -p ~/repos || die "Destination directory does not exist and could not be created"
cd ~/repos || die "Could not cd to destination directory"

while read -r repo_name <&3; do
  repo_name=${repo_name%$'\r'} # handle DOS newlines in input stream
  if [ -d "$repo_name" ]; then
    (cd "$repo_name" && exec git pull)
  else
    git clone "git@bitbucket.org:$user/$repo_name.git" "$repo_name"
  fi
done 3< <(curl -u "$user" "https://api.bitbucket.org/1.0/users/$user" \
            | jq -r '.repositories[].slug')

为了运行这个,你需要安装jq。它可以为 Windows(包括 cygwin)预构建,并且是一种更明智的解析 JSON.

的方法

现在,具体来说,有什么区别?

  • 将当前目录更改为刚好位于目标目录之上,并将任何未来目录更改的范围限定为仅发生在子 shell 中,这意味着您的 test -d 正在检查存储库是否已存在于同一位置在结帐时实际创建的位置。
  • ...具体来说:(cd foo && exec bar) 将目录 foo 的更改范围限定在子 shell 中(不更改脚本其余部分的工作目录),然后执行 bar 仅当 cd 成功时才在该子外壳中。 exec 关键字是次要的性能优化,当 bar 启动时终止子 shell [通过将其进程映像替换为正在启动的程序的进程映像] 而不是潜在地为 [=14 分叉一个新进程=] 到 运行 in.
  • 我们正在使用正斜杠。反斜杠是一种 Windows 主义,bash 的 Windows 端口仅偶尔支持它。
  • 我们没有使用临时文件;相反,我们正在使用进程替换:<(...) 被替换为文件名,该文件名可用于访问命令 ... 的输出,在本例中为 curl | jq 管道。
  • 我们正在将当前工作目录更改为您放置存储库的位置(不要 使用 ~/.ssh -- 这个目录很特殊,并且 OpenSSH 对其文件权限提出了许多要求,这可能使其不适合其他用途)。