Вашият скрипт има редица странности, които вероятно трябва да бъдат коригирани, независимо от непосредствения проблем.
kill -0 "$$" || exit 0
е странно и вероятно не прави нищо полезно. Предполагам вероятно просто не трябва да правите нищо в този случай, тъй като целта на скрипта изглежда е да инсталира компонента, ако липсва, и след това да продължи къмmongodb_status=
... част.- Тъй като по принцип всички команди тук са привилегировани, би било по-логично просто да прекъснете предварително, ако целият скрипт не се изпълнява с привилегии.
Стилистично всичко, което изглежда като sudo bash -c 'singlecommand'
трябва да бъде само sudo singlecommand
; но с предложения рефакторинг изобщо нямате нужда от тях.
Непосредственият проблем с вашия скрипт изглежда е, че отнема известно време на сървъра да започне да слуша на порта, за който сте го конфигурирали. Не знам достатъчно за Mongo, за да ви кажа как правилно да изчакате да ви каже кога е готово „наистина“, но добавяне на sleep
е често срещано (макар и грубо) решение. Друг е да прегледате лог файла, търсейки събитието за слушане.
#!/bin/bash
# Test for privileged access
test -w / ||
{ echo "$0: need to run privileged; aborting" >&2; exit 127; }
startit () {
local log=/var/log/mongodb/mongod.log
service mongod start
while true; do
test -e "$log" && break
sleep 1
done
grep -q 'port: 27017' "$log" ||
tail -0f "$log" |
grep -q 'port: 27017'
}
if [ -f /usr/bin/mongod ]; then
# Send diagnostic messages to standard error
echo "$0: MongoDB is installed on your machine." >&2
else
# Reduce eyesore
echo "$0: MongoDB is not installed; proceed with 4.0 install" >&2
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 68818C72E52529D4
echo "deb http://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" >/etc/apt/sources.list.d/mongodb-org-4.0.list
apt update && apt upgrade -y
apt-get install -y mongodb-org
# not necessary or useful to do a second time
# apt update && apt upgrade -y
apt -y autoremove && apt clean
mkdir -p /data/db
systemctl enable mongod
startit
# service mongod restart # is this really useful and necessary?
fi
echo "$0: database initialization" >&2
# Prefer modern command substitution syntax
mongod_status=$(systemctl is-active mongod)
echo "$mongod_status" >&2
if [[ "${mongod_status}" == "active" ]]
then
echo "$0: MongoDB is already running." >&2
else
echo "$0: MongoDB is not running" >&2
rm -f /var/lib/mongodb/mongod.lock
startit
fi
mongo <<EOF
use fragment
db.createCollection("fragmenthash");
EOF
Не съм напълно доволен от startit
функция -- отначало се провали, защото се опитах да отворя регистрационния файл, когато все още не съществуваше, след това се провали, защото новите редове в регистрационния файл вече съдържаха съобщението за стартиране след една секунда заспиване. Сега все още може да се провали, ако регистрационният файл се добавя и старите регистрационни файлове съдържат съобщението за стартиране от предишна сесия. Но поне това трябва да ви накара да започнете в правилната посока, надявам се.
Ето рефакторинг, който може бъдете по-здрави...
startit () {
local log=/var/log/mongodb/mongod.log
sudo -u mongodb touch "$log"
service mongod start &
local launcher=$!
tail -0f "$log" |
grep -q 'port: 27017'
wait "$launcher"
sleep 1
}
Последният sleep
е малко акт на отчаяние; изглежда, че отнема миг, след като регистрира стартирането, докато не се активира правилно и слуша; и/или може би добавете цикъл за повторен опит около крайния mongo
команда.