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 对其文件权限提出了许多要求,这可能使其不适合其他用途)。
我有一个循环遍历我所有 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 对其文件权限提出了许多要求,这可能使其不适合其他用途)。