如何通过SSH与Sudo在Bash脚本中免密echo写入文件
问题解决:Bash远程写入MariaDB配置文件权限问题
原代码错误点
你写入/etc/mysql/my.cnf的命令存在两个关键问题:
- 权限逻辑与命令语法错误:
> (echo $primary_ssh_password | sudo -S /etc/mysql/my.cnf完全无效,/etc/mysql/my.cnf是配置文件而非可执行命令,sudo后必须跟合法执行程序(如tee、sh -c)才能处理权限写入;且重定向>的优先级高于管道,导致sudo权限根本没作用到文件写入操作上。 - 引号与变量解析风险:双引号嵌套导致配置内容里的特殊字符(如
!)可能被Bash错误解析,同时$primary_ssh_password若包含特殊字符会被意外展开。
修正后的代码写法
方法1:使用sudo tee(推荐,简洁可靠)
合并删除、写入操作,避免冗余步骤:
# 远程删除旧配置(可选,按需保留) $ssh_primary "echo '$primary_ssh_password' | sudo -S rm -f /etc/mysql/my.cnf" # 远程写入新配置 $ssh_primary "echo '$primary_ssh_password' | sudo -S tee /etc/mysql/my.cnf > /dev/null << 'EOF' [client-server] socket = /run/mysqld/mysqld.sock !includedir /etc/mysql/conf.d/ !includedir /etc/mysql/mariadb.conf.d/ [mariadb] log-bin=/var/log/mysql/mysql-bin.log server_id=1 log-basename=master1 binlog-format=mixed log_error=mariadb_primary.err bind-address = 0.0.0.0 EOF" # 重启MariaDB服务 $ssh_primary "echo '$primary_ssh_password' | sudo -S systemctl restart mariadb"
tee命令可通过sudo直接获得文件写入权限,> /dev/null避免配置内容输出到终端<< 'EOF'用单引号包裹here-doc标记,避免本地Bash解析配置内的特殊字符和变量
方法2:使用sudo sh -c执行写入
$ssh_primary "echo '$primary_ssh_password' | sudo -S sh -c 'cat > /etc/mysql/my.cnf' << 'EOF' [client-server] socket = /run/mysqld/mysqld.sock !includedir /etc/mysql/conf.d/ !includedir /etc/mysql/mariadb.conf.d/ [mariadb] log-bin=/var/log/mysql/mysql-bin.log server_id=1 log-basename=master1 binlog-format=mixed log_error=mariadb_primary.err bind-address = 0.0.0.0 EOF"
关于sudo免密的补充说明
如果修改/etc/sudoers后仍需输入密码,检查以下几点:
- 必须用
visudo命令编辑sudoers文件,避免语法错误导致sudo功能失效 - 确保免密规则配置正确,例如针对目标用户添加:
your_username ALL=(ALL) NOPASSWD: /usr/bin/tee, /bin/rm, /bin/systemctl - 确认SSH连接的用户就是sudoers中配置的目标用户
内容的提问来源于stack exchange,提问作者RainMan
相关产品推荐
相关产品推荐

