Я работаю над script, который стал настолько сложным. Я хочу включить простой вариант для обновления его до последней версии. Это мой подход:
set -o errexit
SELF=$(basename $0)
UPDATE_BASE=http://something
runSelfUpdate() {
echo "Performing self-update..."
# Download new version
wget --quiet --output-document=$0.tmp $UPDATE_BASE/$SELF
# Copy over modes from old version
OCTAL_MODE=$(stat -c '%a' $0)
chmod $OCTAL_MODE $0.tmp
# Overwrite old file with new
mv $0.tmp $0
exit 0
}
script, похоже, работает так, как предполагалось, но мне интересно, могут ли быть оговорки с таким подходом. Мне просто трудно полагать, что script может перезаписать себя без каких-либо последствий.
Чтобы быть более ясным, мне интересно, может быть, bash будет читать и выполнять script по очереди, а после mv
, exit 0
может быть чем-то еще из новый script. Я думаю, что я помню, как Windows вела себя с файлами .bat
.
Обновить. Мой оригинальный фрагмент не включал set -o errexit
. Насколько я понимаю, это должно защищать меня от проблем, вызванных wget
.
Кроме того, в этом случае UPDATE_BASE
указывает на местоположение под контролем версий (для облегчения проблем).
Результат. На основании ввода этих ответов я построил этот пересмотренный подход:
runSelfUpdate() {
echo "Performing self-update..."
# Download new version
echo -n "Downloading latest version..."
if ! wget --quiet --output-document="$0.tmp" $UPDATE_BASE/$SELF ; then
echo "Failed: Error while trying to wget new version!"
echo "File requested: $UPDATE_BASE/$SELF"
exit 1
fi
echo "Done."
# Copy over modes from old version
OCTAL_MODE=$(stat -c '%a' $SELF)
if ! chmod $OCTAL_MODE "$0.tmp" ; then
echo "Failed: Error while trying to set mode on $0.tmp."
exit 1
fi
# Spawn update script
cat > updateScript.sh << EOF
#!/bin/bash
# Overwrite old file with new
if mv "$0.tmp" "$0"; then
echo "Done. Update complete."
rm \$0
else
echo "Failed!"
fi
EOF
echo -n "Inserting update process..."
exec /bin/bash updateScript.sh
}