if then 语句以及每个 bash 脚本

if then 语句以及每个 bash 脚本

我正在尝试编写一个 bash 脚本来检查多个文件中的某个字符串,然后如果找到该字符串则将其删除。这是我所拥有的,我认为它会起作用,但只是部分起作用。文件中的条目将被删除,但第二次运行时,我没有收到“无事可做...”消息。

#!/bin/bash
files=(
        '/etc/rsyslog.conf'
        '/etc/rsyslog.d/remote.conf'
        '/etc/rsyslog.d/01-remote.conf'
)

tmpcheck="for f in ${files[*]}; do  cat $f | grep blah | wc -l; done"
#for f in ${files[*]}; do  cat $f | grep collector.acuity.com | wc -l; done

if [[ "$tmpcheck" != 1 ]];then
for f in "${files[@]}";do
                echo -e "Removing blah from $f"
                sed -i "/blah/d" "$f"
        done
                echo -e "Restarting rsyslog service"
                systemctl restart rsyslog.service
else
        echo -e "Nothing to do, blah has been removed from $f"
fi

任何帮助都会有很大帮助。

答案1

tmpcheck其他答案中已经指出了代码中的主要问题(对 的分配)。这是一种稍微不同的方法,假设打印出已修改/未修改文件的名称不是强制性的:

if grep -q -- blah "${files[@]}"
then
    sed -i -e '/blah/d' -- "${files[@]}"
    systemctl restart rsyslog.service
else
    printf '%s\n' 'Nothing to do'
fi

这里的主要想法是:

  • 除非必要,否则在复合命令中直接使用命令的 ( grep) 退出状态if,而不是存储其输出并稍后进行测试;
  • 在循环中调用实用程序效率较低;最好尽可能使用多个文件作为参数来调用它们。

另外,虽然这些不是您显示的代码中的问题:

  • 添加选项结束标记 ( --) 可防止出现不常见的文件名;
  • printf 更安全echo,尤其是在打印扩展结果时。

答案2

我想你想检查 for 循环内的废话。不需要 tmpcheck 变量。相反,您可以$restartrsyslog仅重新启动 rsyslog 一次:

files=(
    '/etc/rsyslog.conf'
    '/etc/rsyslog.d/remote.conf'
    '/etc/rsyslog.d/01-remote.conf'
)

restartrsyslog=

for f in "${files[@]}";do
    if grep -q blah "$f"; then
        echo -e "Removing blah from $f"
        sed -i "/blah/d" "$f"
        restartrsyslog=yes
    else
        echo -e "Nothing to do, blah has been removed from $f"
    fi
done

if [[ -n $restartrsyslog ]] ; then
    echo -e "Restarting rsyslog service"
    systemctl restart rsyslog.service
fi

答案3

您的tmpcheck变量被设置为命令而不是该命令的输出,它永远不会等于 1,因此表达式将始终计算为 true。您应该使用该$( ... )构造来替换命令的输出。您也不需要循环遍历文件,但如果这样做,您不应该使用${files[*]}而应该使用${files[@]}。此外,不需要通过cat管道进入单个文件,grep因为grep可以读取文件,也不需要通过管道grep进入,wc -l因为grep可以-c选择对结果进行计数。最后你为什么要检查它tmpcheck不等于1?如果等于2或更大怎么办?

这对你有用吗?

#!/bin/bash
files=(
    '/etc/rsyslog.conf'
    '/etc/rsyslog.d/remote.conf'
    '/etc/rsyslog.d/01-remote.conf'
)

tmpcheck=$(cat "${files[@]}" | grep -c blah)

if (($tmpcheck>=1)); then
    for f in "${files[@]}";do
        echo -e "Removing blah from $f"
        sed -i "/blah/d" "$f"
    done
    echo -e "Restarting rsyslog service"
    systemctl restart rsyslog.service
else
    echo -e "Nothing to do, blah has been removed from $f"
fi

相关内容