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

SSH远程执行脚本:Heredoc结合sudo切换用户时sh -c报错求助

解决SSH以另用户身份执行脚本的错误问题

你遇到的sh: -c: option requires an argument错误,核心原因是sh -c需要接收一个明确的命令字符串作为参数,但你当前的Here文档写法并没有把脚本内容正确传递给它。下面给你几个可行的解决方案,完全符合你不能分开执行SSH/sudo、不能上传.sh文件的要求:

方案1:用sh -s配合单引号包裹的Here文档(推荐)

这是最直观且易维护的写法,能确保脚本里的变量和命令替换都在远程机器上执行:

ssh -t user@server.com sudo -u user2 sh -s << 'EOF'
cd /home
ls
dir=$(pwd)
echo "$dir"
echo "hello"
# 这里可以继续添加你的其他命令
EOF

关键细节:

  • sh -s:让远程的sh从标准输入读取脚本内容,而不是依赖-c的参数,完美解决了-c缺参数的问题。
  • 'EOF':用单引号包裹Here文档的边界符,阻止本地shell提前解析脚本里的$(pwd)、$dir等变量,确保这些操作都在远程的user2环境下执行。
  • -t:保持这个参数,因为sudo通常需要伪终端来处理可能的密码验证(如果你的user账号执行sudo不需要密码,这个参数也可以保留,不影响)。

方案2:将脚本打包为字符串传给sh -c

如果你的脚本比较短,也可以把所有命令用引号包裹后直接传给sh -c,注意转义内部的引号和变量:

ssh -t user@server.com 'sudo -u user2 sh -c "cd /home && ls && dir=\$(pwd) && echo \"\$dir\" && echo \"hello\""'

这种写法适合短脚本,但长脚本的话可读性会很差,不如方案1方便。

方案3:混合本地/远程变量解析

如果需要部分变量在本地解析(比如本地的环境变量),部分在远程解析,那么可以去掉边界符的单引号,转义需要远程处理的变量:

ssh -t user@server.com sudo -u user2 sh -s << EOF
cd /home
ls
dir=\$(pwd)  # 转义$,让远程机器执行pwd命令
echo "\$dir"
echo "Hello from local user: $USER"  # 不转义,本地shell先替换$USER再传给远程
EOF

为什么原来的命令会报错?

你原来的写法ssh -t user@server.com sudo -u user2 sh -c << EOF中,sh -c期望后面跟一个命令字符串,但Here文档的内容被当作了sh的标准输入,而不是-c的参数,所以sh会提示-c选项需要参数,这就是错误的根源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:35:25