执行Shell脚本abc.sh传参abc时Git报错,请求修复方案
问题
我有一个名为abc.sh的Shell脚本,代码如下:
#!/bin/bash if [ -z $1 ]; then echo "Missing first argument (git repository path)" exit 1 fi arg=$1 CHECKOUT_DIR=$(pwd)/$arg BASE_DIR=$(pwd) set -euo pipefail basename=${1##*/} if [[ $# -lt 1 ]]; then printf '%s: Clone the latest tag on remote.\n' "$basename" >&2 printf 'Usage: %s [other args] <remote>\n' "$basename" >&2 exit 1 fi remote=${*: -1} # Get last argument echo BASE_DIR: $(pwd) echo $CHECKOUT_DIR if [ "$arg" == "abc" ]; then echo $arg >> ${arg}.txt GITREPO=git@xyz.com:Foo/"$arg".git # previousABCReleaseTag=$(git ls-remote --tags $GITREPO |grep "\."|grep -v -|grep -v {| sort -n -t. -k3 -k4) previousABCReleaseTag=$(git ls-remote --tags --exit-code --refs $remote \ | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g' | tail -n1) echo "YYYYYYYYYYYY:"$previousABCReleaseTag else GITREPO=git@xyz.com:Bar/"$arg".git # recentTag=$(git ls-remote --tags $GITREPO |grep "\."|grep -v -|grep -v {| sort -n -t. -k3 -k4) recentTag=$(git ls-remote --tags --exit-code --refs $remote \ | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g' | tail -n1) echo "TTTTTTTTTTTTTTTTTTTTTTTTTT:"$recentTag fi echo $CHECKOUT_DIR # Ensure that we can read the git repo location (NFS) ls -l ${GITREPO} &> /dev/null # Ensure that CHECKOUT_DIR exists mkdir -p ${CHECKOUT_DIR} # Jump into the checkout location so that we can perform the checkout/pull cd ${CHECKOUT_DIR} function repoclone() { if [ -n "$username" ]; then echo "Build through Jenkins job" echo $arg if [ "$arg" == "abc" ]; then previousABCReleaseTag=$(git ls-remote --tags https://GITHUB.XYZ.com"$arg" |grep "\."|grep -v -|grep -v {| sort -n -t. -k3 -k4) tagNumber=${previousABCReleaseTag##*v} echo "abc= v$tagNumber" >> "$arg.txt" echo "abc= v$tagNumber" >> durlov.txt sh ${BASE_DIR}/git-clone-latest-tag.sh https://github.xyz.com"$arg" else recentTag=$(git ls-remote --tags https://github.xyz.com"$arg".git |grep "\."|grep -v -|grep -v {| sort -n -t. -k3 -k4) tag = ${recentTag##*v} echo "$arg= v$tag" >> "$arg.txt" sh ${BASE_DIR}/git-clone-latest-tag.sh https://github.xyz.com"$arg".git fi else echo $GITREPO if [ "$arg" == "abc" ]; then set -x echo "abc= $previousABCReleaseTag" >> ${arg}.txt #git clone -b $ta ${GITREPO} echo Current working dir: ${BASE_DIR} git remote add ${arg} ${GITREPO} #sh ${BASE_DIR}/git-clone-latest-tag.sh ${GITREPO} # Ensure that we can read the git repo location (NFS) git clone ${GITREPO} git checkout tags/$previousABCReleaseTag else set -x echo "$arg= $recentTag" >> ${arg}.txt #git clone -b $tag --single-branch --depth 1 ${GITREPO} git remote add ${arg} ${GITREPO} #sh ${BASE_DIR}/git-clone-latest-tag.sh ${GITREPO} git clone ${GITREPO} git checkout tags/$recentTag fi fi } if [ ! -d ${CHECKOUT_DIR}/.git ]; then cd ${CHECKOUT_DIR} # Clone the git repository echo "Cloning Git repository to ${CHECKOUT_DIR}" repoclone else rm -rf $CHECKOUT_DIR echo $CHECKOUT_DIR echo "Directory deleted ,new one will be created" mkdir -p ${CHECKOUT_DIR} cd ${CHECKOUT_DIR} repoclone fi cd $CHECKOUT_DIR echo "111111111111111111$CHECKOUT_DIR" if [ "$arg" == "abc" ]; then gradle -Pproduction=true build else make all fi
执行命令./abc.sh abc时,出现如下错误:
fatal: 'abc' does not appear to be a git repository fatal: Could not read from remote repository.
问题分析
- 远程地址错误:脚本中
remote=${*: -1}会取最后一个参数作为远程仓库地址,当执行./abc.sh abc时,remote的值是abc,这显然不是有效的Git远程仓库地址,导致后续git ls-remote逻辑出错。 - 无效的
git remote add命令:在repoclone函数中,执行git clone之前先调用了git remote add ${arg} ${GITREPO},此时当前目录不是Git仓库,这个命令毫无意义,且会触发报错。 - 路径切换问题:
git clone会在当前目录下创建一个与仓库同名的子目录(比如clonegit@xyz.com:Foo/abc.git会生成abc目录),后续的git checkout需要进入这个子目录执行,否则会在空目录中执行Git命令导致报错。 - 变量赋值语法错误:脚本中
tag = ${recentTag##*v}存在空格,不符合Shell变量赋值的语法要求,会被当作命令执行导致错误。
修复方案
修复步骤
- 替换
git ls-remote中的remote变量为正确的仓库地址GITREPO; - 移除无效的
git remote add命令; - 在
git clone后切换到仓库子目录再执行git checkout; - 修正变量赋值的语法错误,去掉
tag = ...中的空格; - 完善目录存在性检查的路径逻辑,确保检测的是仓库子目录下的
.git文件夹。
修复后的完整脚本
#!/bin/bash if [ -z "$1" ]; then echo "Missing first argument (git repository path)" exit 1 fi arg="$1" CHECKOUT_DIR=$(pwd)/"$arg" BASE_DIR=$(pwd) set -euo pipefail basename=${1##*/} if [[ $# -lt 1 ]]; then printf '%s: Clone the latest tag on remote.\n' "$basename" >&2 printf 'Usage: %s [other args] <repo-name>\n' "$basename" >&2 exit 1 fi echo BASE_DIR: $(pwd) echo $CHECKOUT_DIR if [ "$arg" == "abc" ]; then echo "$arg" >> "${arg}.txt" GITREPO=git@xyz.com:Foo/"$arg".git previousABCReleaseTag=$(git ls-remote --tags --exit-code --refs "$GITREPO" \ | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g' | tail -n1) echo "YYYYYYYYYYYY:"$previousABCReleaseTag else GITREPO=git@xyz.com:Bar/"$arg".git recentTag=$(git ls-remote --tags --exit-code --refs "$GITREPO" \ | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g' | tail -n1) echo "TTTTTTTTTTTTTTTTTTTTTTTTTT:"$recentTag fi echo $CHECKOUT_DIR # Ensure that CHECKOUT_DIR exists mkdir -p "${CHECKOUT_DIR}" # Jump into the checkout location so that we can perform the checkout/pull cd "${CHECKOUT_DIR}" function repoclone() { if [ -n "${username:-}" ]; then echo "Build through Jenkins job" echo "$arg" if [ "$arg" == "abc" ]; then previousABCReleaseTag=$(git ls-remote --tags https://GITHUB.XYZ.com/"$arg" |grep "\."|grep -v -|grep -v {| sort -n -t. -k3 -k4) tagNumber=${previousABCReleaseTag##*v} echo "abc= v$tagNumber" >> "$arg.txt" echo "abc= v$tagNumber" >> durlov.txt sh "${BASE_DIR}"/git-clone-latest-tag.sh https://github.xyz.com/"$arg" else recentTag=$(git ls-remote --tags https://github.xyz.com/"$arg".git |grep "\."|grep -v -|grep -v {| sort -n -t. -k3 -k4) tag=${recentTag##*v} echo "$arg= v$tag" >> "$arg.txt" sh "${BASE_DIR}"/git-clone-latest-tag.sh https://github.xyz.com/"$arg".git fi else echo "$GITREPO" if [ "$arg" == "abc" ]; then set -x echo "abc= $previousABCReleaseTag" >> "${arg}.txt" echo Current working dir: "${BASE_DIR}" # Clone the repo and enter the directory git clone "$GITREPO" cd "$arg" git checkout tags/"$previousABCReleaseTag" else set -x echo "$arg= $recentTag" >> "${arg}.txt" git clone "$GITREPO" cd "$arg" git checkout tags/"$recentTag" fi fi } if [ ! -d "${CHECKOUT_DIR}/${arg}/.git" ]; then echo "Cloning Git repository to ${CHECKOUT_DIR}" repoclone else rm -rf "${CHECKOUT_DIR}" echo "${CHECKOUT_DIR}" echo "Directory deleted, new one will be created" mkdir -p "${CHECKOUT_DIR}" cd "${CHECKOUT_DIR}" repoclone fi cd "${CHECKOUT_DIR}/${arg}" echo "111111111111111111${CHECKOUT_DIR}/${arg}" if [ "$arg" == "abc" ]; then gradle -Pproduction=true build else make all fi
内容的提问来源于stack exchange,提问作者pranami
相关产品推荐
相关产品推荐

