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

SSH远程执行for循环异常:循环在源服务器运行而非目标服务器

解决SSH远程执行循环时本地展开命令/变量的问题

问题分析

你遇到的核心问题是:使用<< EOT的here-doc时,bash默认会在本地服务器展开所有的命令替换(如cat file.txt)和变量引用(如${appName}),导致循环逻辑在本地执行,而非目标服务器。即使把file.txt放到本地,变量也会被本地提前替换,无法传递到远程循环中。

解决方案

根据file.txt的存放位置,提供两种可行方案:

场景1:file.txt在目标服务器上

通过给here-doc分界符添加单引号(<< 'EOT'),禁止本地的命令/变量展开,让所有代码在目标服务器执行。同时改用sudo -u user1直接执行命令,避免sudo su - user1切换shell导致后续命令失效的问题:

ssh  -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /app/.ssh/key.pem -t  abc@$server1 << 'EOT'
    sudo -u user1 bash -c '
        cd /app/dir1
        # 用$(cat)替代反引号,更规范且避免嵌套问题
        for appName in $(cat file.txt)
        do
            mv /app/dir1/httpd/${appName}/ /app/dir1/backup/${appName}/
            cp -R /app/dir2/source/${appName}/ /app/dir1/httpd/${appName}
        done
    '
EOT

场景2:file.txt在本地服务器上

将本地file.txt的内容传递到目标服务器,用while read循环处理(比for更可靠,能处理带空格的文件名):

# 本地读取文件内容,通过管道传递给远程服务器
cat file.txt | ssh  -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /app/.ssh/key.pem -t  abc@$server1 '
    sudo -u user1 bash -c "
        cd /app/dir1
        while read -r appName
        do
            # 转义变量避免本地提前展开
            mv /app/dir1/httpd/\${appName}/ /app/dir1/backup/\${appName}/
            cp -R /app/dir2/source/\${appName}/ /app/dir1/httpd/\${appName}
        done
    "
'

关键注意事项

  • 优先使用$(命令)替代反引号`命令`,前者语法更清晰,支持嵌套。
  • 避免使用sudo su - user1切换shell,改用sudo -u user1 bash -c '命令'直接以目标用户身份执行脚本逻辑,避免shell切换导致的命令中断。
  • 当需要远程执行包含变量/命令的脚本时,务必通过单引号包裹或转义,防止本地提前展开。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 14:54:07