首页 > 解决方案 > 来自 github 的自我更新 bash 脚本

问题描述

我正在尝试制作我的脚本来检查我在 github 中的 repo 是否有更新,然后获取更新并用新代码替换旧代码并运行“不是旧代码”的新代码。我想出了这个,但它在完成后更新

self_update() {
    cd $(dirname $0)
    git fetch > a.txt 1> /dev/null 2> /dev/null
    git reset --hard >> a.txt 1> /dev/null 2> /dev/null
    git pull >> a.txt 1> /dev/null 2> /dev/null
    rm a.txt
    chmod +x "$(basename $0)"
    cd -
}
self_update
echo “some code”

编辑:我在stackoverflow找到了下面的代码,它更新了我的脚本。然而,它进入了一个循环,从不运行新的或旧的代码,不知道为什么。

#!/bin/bash

SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT")
SCRIPTNAME="$0"
ARGS="( $@ )"
BRANCH="master"

self_update() {
    cd $SCRIPTPATH
    git fetch

    [ -n $(git diff --name-only origin/$BRANCH | grep $SCRIPTNAME) ] && {
        echo "Found a new version of me, updating myself..."
        git pull --force
        git checkout $BRANCH
        git pull --force
        echo "Running the new version..."
        exec "$SCRIPTNAME" "${ARGS[@]}"

        # Now exit this old instance
        exit 1
    }
    echo "Already the latest version."
}
self_update
echo “some code”

重复输出:

 Found a new version of me, updating myself...
 HEAD is now at 5dd5111 Update tool
 Already up to date
 Already on ‘master’
 Your branch is up to date with origin/master

它不会停止打印输出,直到我 CTRL-C 输出:执行:bash -x /opt/script/firstScript -h

++ readlink -f /opt/script/firstScript
+ SCRIPT=/opt/script/firstScript  
++ dirname /opt/script/firstScript
+ SCRIPTPATH=/opt/script                                
+ SCRIPTNAME=/opt/script/firstScript
+ ARGS='( -h )'
+ BRANCH=master
+ self_update      
+ cd /opt/script
+ git fetch                                                
++ git diff --name-only origin/master
++ grep /opt/script/firstScript
+ '[' -n ']'                                               
+ echo 'Found a new version of me, updating myself...'
Found a new version of me, updating myself...
+ git pull --force 
Already up to date.  
+ git checkout master
Already on 'master'
Your branch is up to date with 'origin/master'.
+ git pull --force
Already up to date.
+ echo 'Running the new version...'
Running the new version...
+ exec bash -x /opt/script/firstScript '( -h )'
++ readlink -f /opt/script/firstScript
+ SCRIPT=/opt/script/firstScript
++ dirname /opt/script/firstScript
+ SCRIPTPATH=/opt/script
+ SCRIPTNAME=/opt/script/firstScript
+ ARGS='( ( -h ) )'
+ BRANCH=master
+ self_update
+ cd /opt/script
+ git fetch
++ git diff --name-only origin/master
++ grep /opt/script/firstScript
+ '[' -n ']'
+ echo 'Found a new version of me, updating myself...'
Found a new version of me, updating myself...
+ git pull --force
Already up to date.
+ git checkout master
Already on 'master'
Your branch is up to date with 'origin/master'.
+ git pull --force
Already up to date.
+ echo 'Running the new version...'
Running the new version...
+ exec bash -x /opt/script/firstScript '( ( -h ) )'
++ readlink -f /opt/script/firstScript
+ SCRIPT=/opt/script/firstScript
++ dirname /opt/script/firstScript
+ SCRIPTPATH=/opt/script
+ SCRIPTNAME=/opt/script/firstScript
+ ARGS='( ( ( -h ) ) )'
+ BRANCH=master
+ self_update
+ cd /opt/script
+ git fetch
++ git diff --name-only origin/master
++ grep /opt/script/firstScript
+ '[' -n ']'
+ echo 'Found a new version of me, updating myself...'
Found a new version of me, updating myself...
+ git pull --force
Already up to date.
+ git checkout master
Already on 'master'
Your branch is up to date with 'origin/master'.
+ git pull --force
^C

输出:执行:bash /opt/script/firstScript -h

Found a new version of me, updating myself...
Already up to date.
Your branch is up to date with 'origin/master'.
Already up to date.
Running the new version...
Found a new version of me, updating myself...
Already up to date.
Your branch is up to date with 'origin/master'.
Already up to date.
Running the new version...
Found a new version of me, updating myself...
Already up to date.
Your branch is up to date with 'origin/master'.
Already up to date.
Running the new version...
Found a new version of me, updating myself...
Already up to date.
Your branch is up to date with 'origin/master'.
Already up to date.
Running the new version...
Found a new version of me, updating myself...
Already up to date.
Your branch is up to date with 'origin/master'.
Already up to date.
Running the new version...
Found a new version of me, updating myself...
Already up to date.
Your branch is up to date with 'origin/master'.
Already up to date.
Running the new version...
Found a new version of me, updating myself...
Already up to date.
Your branch is up to date with 'origin/master'.
Already up to date.
Running the new version...
Found a new version of me, updating myself...
^C

标签: linuxbashgitgithubself-updating

解决方案


脚本无法自行更新可能有多种原因。暂时搁置“为什么”,考虑使用基于环境变量的“双重调用”守卫。它将防止重复尝试更新。

self_update() {
    [ "$UPDATE_GUARD" ] && return
    export UPDATE_GUARD=YES

    cd $SCRIPTPATH
    git fetch

    [ -n $(git diff --name-only origin/$BRANCH | grep $SCRIPTNAME) ] && {
        echo "Found a new version of me, updating myself..."
        git pull --force
        git checkout $BRANCH
        git pull --force
        echo "Running the new version..."
        exec "$SCRIPTNAME" "${ARGS[@]}"

        # Now exit this old instance
        exit 1
    }
    echo "Already the latest version."
}

此外,self_update如果它可能会影响运行脚本,请考虑将其更改为返回到原始 cwd。


推荐阅读