来自github的自我更新bash脚本 [英] Self updating bash script from github
问题描述
我正在尝试让我的脚本检查github中我的仓库中是否有更新,然后获取更新并将旧代码替换为新代码,然后运行新代码而不是旧代码".我想出了这个,但完成后会更新
I am trying to make my script to check if there is an update from my repo in github and then get the updates and replace old code with new one and run the new code "not the old one". I came up with this but it updates after it finishes
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 中找到了以下代码更新我的脚本.但是,它进入了循环,并且从不运行新的或旧的代码,不知道为什么.
I found the below code here stackoverflow and it updates my script. However, it goes into a loop and never runs the new or old code, not sure why.
#!/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
直到i CTRL-C才会停止打印输出 输出:执行以下命令:bash -x/opt/script/firstScript -h
It does not stop printing the output till i CTRL-C Output: Executed with: 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
Output: Executed with: 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
推荐答案
阅读bash -x输出后,我可以为您重写脚本
After reading bash -x output I can give you a rewrite of the script
#!/bin/bash
# Here I remark changes
SCRIPT="$(readlink -f "$0")"
SCRIPTFILE="$(basename "$SCRIPT")" # get name of the file (not full path)
SCRIPTPATH="$(dirname "$SCRIPT")"
SCRIPTNAME="$0"
ARGS=( "$@" ) # fixed to make array of args (see below)
BRANCH="master"
self_update() {
cd "$SCRIPTPATH"
git fetch
# in the next line
# 1. added double-quotes (see below)
# 2. removed grep expression so
# git-diff will check only script
# file
[ -n "$(git diff --name-only "origin/$BRANCH" "$SCRIPTFILE")" ] && {
echo "Found a new version of me, updating myself..."
git pull --force
git checkout "$BRANCH"
git pull --force
echo "Running the new version..."
cd - # return to original working dir
exec "$SCRIPTNAME" "${ARGS[@]}"
# Now exit this old instance
exit 1
}
echo "Already the latest version."
}
self_update
echo "some code"
低于1 . ARGS="( $@ )"
绝对应为ARGS=( "$@" )
,否则在使用'( -h )'
参数而不是-h
执行更新脚本之后(通常,它以所有参数串联在单个字符串中执行,即,您将其作为/opt/script/firstScript -a -b -c
运行,并在更新后以/opt/script/firstScript '( -a -b -c )'
Below 1. ARGS="( $@ )"
definitely should be ARGS=( "$@" )
, otherwise after update script is executed with '( -h )'
argument instead of -h
(in general, it is executed with all arguments concatenated in a single string, i.e. you run it as /opt/script/firstScript -a -b -c
, and after update it runs as /opt/script/firstScript '( -a -b -c )'
低于2 . $(...)
周围必须用双引号引起来,否则[ -n
使用]
作为输入参数并返回true,因为它不为空(而git-diff|grep
的空输出在[ -n
的参数列表中被忽略)(这是造成循环的原因)
Below 2. Double quotes are necessary around $(...)
, otherwise [ -n
uses ]
as input argument and returns true because it is not empty (while the empty output of git-diff|grep
is ignored in argument list of [ -n
) (That was the loop cause)
这篇关于来自github的自我更新bash脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!