Bash 循环遍历目录内的所有目录,如果在每个目录的特定文件中找到任何字符串实例,则执行此操作

Bash 循环遍历目录内的所有目录,如果在每个目录的特定文件中找到任何字符串实例,则执行此操作

我有一项服务,它利用用户指定的唯一端口进行远程连接。我安装了此服务的多个实例,并编写了一个 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

相关内容