You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本循环SSH服务器修改SELinux模式时仅检查首台的问题

批量修改远程SELinux配置脚本的问题修复

问题根源

你的脚本中,远程执行的if判断里的$(grep -c SELINUX=enforcing $selinux_path)被本地Shell提前解析了,而非在目标服务器上执行。因为你用双引号包裹ssh命令内容,本地Shell会先执行这个命令替换,拿到本地的结果后再传递给远程服务器,导致后续服务器的判断逻辑完全错误(比如第一台执行后本地无对应文件,结果为0,后续所有远程服务器都走else分支)。

修复后的脚本方案

方案一:使用单引号包裹远程命令(需处理本地变量嵌入)

#!/bin/bash

selinux_path=/opt/configtest
hosts=(server1 server2)

for my_hosts in "${hosts[@]}"
do
    ssh -q -o "StrictHostKeyChecking no" root@${my_hosts} '
        if [ $(grep -c SELINUX=enforcing '$selinux_path') -ne 0 ]
        then 
            echo "------------------------------------------------"
            echo "'${my_hosts}'"
            echo "------------------------------------------------"
            sed -i '\''s/SELINUX=enforcing/SELINUX=permissive/g'\'' '$selinux_path'
            echo "Selinux has been changed to permissive"
            cat '$selinux_path'
        else
            echo "------------------------------------------------"
            echo "'${my_hosts}'"
            echo "------------------------------------------------"
            echo "Selinux has already been changed to permissive"
            cat '$selinux_path'
        fi    
    '
done 

方案二:使用Here Document(更易读,避免引号转义)

#!/bin/bash

selinux_path=/opt/configtest
hosts=(server1 server2)

for my_hosts in "${hosts[@]}"
do
    ssh -q -o "StrictHostKeyChecking no" root@${my_hosts} <<EOF
        if [ \$(grep -c SELINUX=enforcing $selinux_path) -ne 0 ]
        then 
            echo "------------------------------------------------"
            echo "$my_hosts"
            echo "------------------------------------------------"
            sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' $selinux_path
            echo "Selinux has been changed to permissive"
            cat $selinux_path
        else
            echo "------------------------------------------------"
            echo "$my_hosts"
            echo "------------------------------------------------"
            echo "Selinux has already been changed to permissive"
            cat $selinux_path
        fi    
EOF
done 

关键修改说明

  1. 避免本地解析远程命令:
    • 方案一中,外层用单引号包裹远程命令,让本地Shell不解析其中的$(...)命令替换。
    • 方案二中,对远程的$(...)添加转义符\$,确保该命令替换在远程服务器执行。
  2. 本地变量传递:
    • 方案一中,本地变量${my_hosts}和${selinux_path}通过'${变量名}'的方式嵌入单引号,实现本地值传递给远程。
    • 方案二中,直接使用未转义的本地变量,让本地Shell提前替换后传递给远程。
  3. 引号冲突处理:方案一中sed命令的单引号需转义为\',避免和外层单引号冲突。

内容的提问来源于stack exchange,提问作者Scott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 08:35:19