Bash shell 脚本无法连接到 MongoDB 即使状态为活动
Bash shell script not getting connect to MongoDB even if status is active
使用 Ubuntu 18.04。我要安装以下 bash 脚本和 运行 MongoDB。 IT 检查是否安装了 MongoDB 和 运行 一些 mongo shell 命令:
#!/bin/bash
if [ -f /usr/bin/mongod ]; then
echo "MongoDB is installed on your machine."
kill -0 "$$" || exit
else
password=password
echo "********************* MongoDB 4.0 INSTALL **************************"
echo "MongoDB is is not installed."
echo "******************************************************************"
echo $password | sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 68818C72E52529D4
echo $password | sudo bash -c "echo deb http://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo bash -c "apt update && apt upgrade -y"
sudo bash -c "apt-get install -y mongodb-org"
sudo bash -c "apt update && apt upgrade -y"
echo 'y' | sudo bash -c "apt autoremove && apt clean"
sudo bash -c "mkdir /data /data/db"
sudo bash -c "systemctl enable mongod" #enables Mongo on system startup
sudo bash -c "service mongod start"
sudo bash -c "service mongod restart"
kill -0 "$$" || exit
echo "********************* MongoDB Create DB and Collection **************************"
fi
mongod_status=`systemctl is-active mongod`
echo "${mongod_status}"
if [[ "${mongod_status}" == "active" ]]
then
echo "MongoDB is already running."
else
echo "MongoDB is not running"
rm /var/lib/mongodb/mongod.lock
sudo bash -c "service mongod start"
fi
mongo <<EOF
use fragment
db.createCollection("fragmenthash");
EOF
如果我的系统没有安装 MongoDB,此脚本会安装并启动它。然后它检查状态,即“活动”。但是当它执行 mongo <<EOF section
时,它 returns
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
2021-05-19T10:06:01.134+0000 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:356:17
@(connect):2:6
exception: connect failed
即使 MongoDB 的状态为 Active 仍然会出现此错误。然而,如果 MongoDB 已经安装,它会成功执行整个脚本并创建数据库和集合。请帮忙。
你的脚本有很多奇怪的地方,不管眼前的问题是什么,都应该加以纠正。
kill -0 "$$" || exit 0
很奇怪,可能没有任何用处。我 猜想 在这种情况下你可能根本不应该做任何事情,因为脚本的目的似乎是安装缺少的组件,然后继续 mongodb_status=
。 ..部分.
- 因为基本上这里的所有命令都是特权的,如果整个脚本不是 运行 特权,那么提前中止会更有意义。
在文体上,所有看起来像 sudo bash -c 'singlecommand'
的东西都应该只是 sudo singlecommand
;但是通过提议的重构,您根本不需要这些。
您的脚本的直接问题似乎是服务器需要一段时间才能开始侦听您为其配置的端口。我对 Mongo 的了解还不够多,无法告诉您如何正确地等待它“真正”启动时告诉您,但是添加 sleep
是一种常见(尽管很粗糙)的解决方法。另一种是检查日志文件,寻找监听事件。
#!/bin/bash
# Test for privileged access
test -w / ||
{ echo "[=10=]: 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 "[=10=]: MongoDB is installed on your machine." >&2
else
# Reduce eyesore
echo "[=10=]: 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 "[=10=]: database initialization" >&2
# Prefer modern command substitution syntax
mongod_status=$(systemctl is-active mongod)
echo "$mongod_status" >&2
if [[ "${mongod_status}" == "active" ]]
then
echo "[=10=]: MongoDB is already running." >&2
else
echo "[=10=]: 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
有点走投无路;在记录启动后直到它正常启动并收听时似乎需要一点时间; and/or 可能会在最后的 mongo
命令周围添加一个重试循环。
使用 Ubuntu 18.04。我要安装以下 bash 脚本和 运行 MongoDB。 IT 检查是否安装了 MongoDB 和 运行 一些 mongo shell 命令:
#!/bin/bash
if [ -f /usr/bin/mongod ]; then
echo "MongoDB is installed on your machine."
kill -0 "$$" || exit
else
password=password
echo "********************* MongoDB 4.0 INSTALL **************************"
echo "MongoDB is is not installed."
echo "******************************************************************"
echo $password | sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 68818C72E52529D4
echo $password | sudo bash -c "echo deb http://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo bash -c "apt update && apt upgrade -y"
sudo bash -c "apt-get install -y mongodb-org"
sudo bash -c "apt update && apt upgrade -y"
echo 'y' | sudo bash -c "apt autoremove && apt clean"
sudo bash -c "mkdir /data /data/db"
sudo bash -c "systemctl enable mongod" #enables Mongo on system startup
sudo bash -c "service mongod start"
sudo bash -c "service mongod restart"
kill -0 "$$" || exit
echo "********************* MongoDB Create DB and Collection **************************"
fi
mongod_status=`systemctl is-active mongod`
echo "${mongod_status}"
if [[ "${mongod_status}" == "active" ]]
then
echo "MongoDB is already running."
else
echo "MongoDB is not running"
rm /var/lib/mongodb/mongod.lock
sudo bash -c "service mongod start"
fi
mongo <<EOF
use fragment
db.createCollection("fragmenthash");
EOF
如果我的系统没有安装 MongoDB,此脚本会安装并启动它。然后它检查状态,即“活动”。但是当它执行 mongo <<EOF section
时,它 returns
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
2021-05-19T10:06:01.134+0000 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:356:17
@(connect):2:6
exception: connect failed
即使 MongoDB 的状态为 Active 仍然会出现此错误。然而,如果 MongoDB 已经安装,它会成功执行整个脚本并创建数据库和集合。请帮忙。
你的脚本有很多奇怪的地方,不管眼前的问题是什么,都应该加以纠正。
kill -0 "$$" || exit 0
很奇怪,可能没有任何用处。我 猜想 在这种情况下你可能根本不应该做任何事情,因为脚本的目的似乎是安装缺少的组件,然后继续mongodb_status=
。 ..部分.- 因为基本上这里的所有命令都是特权的,如果整个脚本不是 运行 特权,那么提前中止会更有意义。
在文体上,所有看起来像 sudo bash -c 'singlecommand'
的东西都应该只是 sudo singlecommand
;但是通过提议的重构,您根本不需要这些。
您的脚本的直接问题似乎是服务器需要一段时间才能开始侦听您为其配置的端口。我对 Mongo 的了解还不够多,无法告诉您如何正确地等待它“真正”启动时告诉您,但是添加 sleep
是一种常见(尽管很粗糙)的解决方法。另一种是检查日志文件,寻找监听事件。
#!/bin/bash
# Test for privileged access
test -w / ||
{ echo "[=10=]: 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 "[=10=]: MongoDB is installed on your machine." >&2
else
# Reduce eyesore
echo "[=10=]: 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 "[=10=]: database initialization" >&2
# Prefer modern command substitution syntax
mongod_status=$(systemctl is-active mongod)
echo "$mongod_status" >&2
if [[ "${mongod_status}" == "active" ]]
then
echo "[=10=]: MongoDB is already running." >&2
else
echo "[=10=]: 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
有点走投无路;在记录启动后直到它正常启动并收听时似乎需要一点时间; and/or 可能会在最后的 mongo
命令周围添加一个重试循环。