You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行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.

问题分析

  1. 远程地址错误:脚本中remote=${*: -1}会取最后一个参数作为远程仓库地址,当执行./abc.sh abc时,remote的值是abc,这显然不是有效的Git远程仓库地址,导致后续git ls-remote逻辑出错。
  2. 无效的git remote add命令:在repoclone函数中,执行git clone之前先调用了git remote add ${arg} ${GITREPO},此时当前目录不是Git仓库,这个命令毫无意义,且会触发报错。
  3. 路径切换问题:git clone会在当前目录下创建一个与仓库同名的子目录(比如clonegit@xyz.com:Foo/abc.git会生成abc目录),后续的git checkout需要进入这个子目录执行,否则会在空目录中执行Git命令导致报错。
  4. 变量赋值语法错误:脚本中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 23:06:21