Sto lavorando a uno script che è diventato così complesso che voglio includere un'opzione semplice per aggiornarlo alla versione più recente. Questo è il mio approccio:È un approccio di autoaggiornamento valido per uno script bash?
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
}
Lo script sembra funzionare come previsto, ma mi chiedo se ci potrebbe essere avvertimenti con questo tipo di approccio. Ho solo difficoltà a credere che uno script possa sovrascrivere se stesso senza ripercussioni.
Per essere più chiaro, mi chiedo, se, forse, bash sarebbe leggere ed eseguire lo script linea per linea e dopo il mv
, il exit 0
potrebbe essere qualcos'altro dal nuovo script. Penso di ricordare che Windows si comporta in questo modo con i file .bat
.
Aggiornamento: il mio snippet originale non include set -o errexit
. A mio parere, questo dovrebbe tenermi al sicuro da problemi causati da wget
.
Inoltre, in questo caso, UPDATE_BASE
punta a una posizione sotto il controllo della versione (per alleviare i dubbi).
Risultato: Sulla base del contributo di queste risposte, ho costruito questo nuovo approccio:
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
}
non sarebbe meglio sostituire il 'exit 0 'con' exec "$ 0" 'più eventuali argomenti che è necessario trasmettere (forse:' exec "$ 0" "$ @" ')?Cioè, dopo aver affrontato la meccanica del download, verificando e sostituendo la precedente incarnazione dello script come discusso da @shellter. –
@ JonathanLeffler Sì, forse. Per ora, volevo mantenere questa azione separata e breve in modo che non interferisse con il resto della sceneggiatura. Una volta che avrò fiducia nell'approccio, potrei estenderlo. –
Si noti che ottenere le autorizzazioni con stat richiede un diverso flag e formato su osx. L'equivalente è 'stat -f '% A' $ 0'. – meonlol