AOSP镜像至本地Gerrit的Bash脚本异常及SSH连接优化需求
AOSP镜像到本地Gerrit的脚本修正方案
问题原因
repo forall默认调用系统默认Shell(如sh),不支持Bash独有的[[ ... =~ ... ]]正则匹配语法,导致if条件失效。- 原脚本每次执行SSH命令和Git推送都会新建一次SSH连接,频繁连接会给Gerrit服务器带来额外负载。
修正后的实现方案
核心改进
- 强制
repo forall使用Bash执行命令,解决语法兼容性问题。 - 利用SSH连接复用功能,建立一次持久连接供所有操作使用,大幅减少连接次数。
- 改用精确字符串匹配替代正则匹配,避免误判。
完整脚本
#!/bin/bash # 初始化并同步AOSP镜像仓库 repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r9 --mirror repo sync # 获取所有仓库路径,转为换行分隔格式便于后续处理 repo_list=$(repo list -p | tr ' ' '\n') # 配置SSH连接复用参数,提前建立主连接 SSH_CONTROL_PATH="/tmp/gerrit-ssh-%r@%h:%p" ssh -fN -p 29418 -o ControlMaster=yes -o ControlPath="${SSH_CONTROL_PATH}" gerritadmin@local-gerrit-host # 遍历所有仓库,执行项目创建与代码推送 repo forall -c ' # 将全局传递的仓库列表转为数组 IFS=$'\''\n'\'' read -r -d '\'''\'' -a repo_arr <<< "$REPO_LIST" # 精确匹配当前仓库路径 for repo in "${repo_arr[@]}"; do if [[ "$repo" == "$REPO_PATH" ]]; then # 复用SSH连接创建Gerrit项目 ssh -o ControlPath="${SSH_CONTROL_PATH}" gerritadmin@local-gerrit-host gerrit create-project aosp/"${REPO_PATH}" --parent All-Projects || echo "Failed to create project for ${REPO_PATH}" break fi done # 复用SSH连接推送所有分支与标签 git push "ssh://gerritadmin@local-gerrit-host:29418/aosp/${REPO_PATH}" +refs/heads/* +refs/tags/* || echo "Failed to push ${REPO_PATH}" ' REPO_LIST="${repo_list}" # 关闭SSH主连接 ssh -o ControlPath="${SSH_CONTROL_PATH}" gerritadmin@local-gerrit-host -O exit
关键细节说明
- 变量传递:通过
repo forall的末尾参数REPO_LIST="${repo_list}"将外部变量传入循环内的Shell环境。 - SSH复用机制:
ControlMaster=yes创建主连接,后续命令通过ControlPath复用该连接,避免重复握手。 - 精确匹配:用数组遍历+字符串相等判断替代正则匹配,确保只处理当前仓库,避免子路径误匹配。
内容的提问来源于stack exchange,提问作者user4948798
相关产品推荐
相关产品推荐

