我有一项服务,它利用用户指定的唯一端口进行远程连接。我安装了此服务的多个实例,并编写了一个 bash 脚本来自动执行安装。我的安装程序有一个内置检查,以防止我自己的愚蠢尝试绑定到之前安装的实例上已配置的端口。以前我使用 lsof 的方式如下...
if [[ -z $(lsof -i :${service_port}) ]]; then
工作得很好,直到我意识到有时我会在一段时间内关闭实例,而 lsof 只检查当前正在使用的端口。
所以现在我又回过头来抓取每个实例的配置文件(很酷?不再依赖 lsof),这些文件很小,每个只有大约 5kb,可以快速迭代。
我最初尝试了这个(每个安装都在 installs_dir 中它自己的文件夹中)...
while read -e -p "Port: " -i "" service_port; do
for each_install in "${installs_dir}/"*
do
if grep -q Port=${service_port} "$each_install"/main.cfg; then
printf "Port ${service_port} in use, try another port\n"
break
else
# Write Config
fi
done
done
但是它当然会在每个目录上触发。有没有办法让它只写入一次而不产生while循环夹层,或者可能是另一个不必搜索所有文件的命令?
答案1
明白了...只需要使用 -c 标志来计算 grep 中的匹配项,使用 -q 来保持其干净和安静,然后退出 for 循环并确保没有匹配项。
installs_dir="/my/dir"
while read -e -p "Service Port: " -i "" service_port; do
s=0
for each_install in "${installs_dir}/"*; do
while grep -cq Port=${service_port} ${each_install}/main.cfg; do
let "s++"
break
done
done
[ ${s} != 0 ] && printf "A server is already assigned to that port, try again.\n"
[ ${s} == 0 ] && printf "Port assigned.\n" && break
done