Windows PowerShell通过SSH执行sed命令报错:未终止的s命令
问题解决:PowerShell中通过SSH执行sed命令报错"unterminated `s' command"
问题背景
Linux环境下可正常执行的sed命令:
sed "s/#\?\(PasswordAuthentication\s*\).*$/\1 no/" /etc/ssh/sshd_config
但在Windows PowerShell中通过以下命令远程执行时:
pwsh -c ssh root@161.97.108.95 -p 22 sed "s/#\?\(PasswordAuthentication\s*\).*$/\1 no/" /etc/ssh/sshd_config
出现错误:
sed: -e expression #1, char 35: unterminated `s' command
已设置编码为UTF-8:
$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
但问题仍存在,调试发现命令被篡改,核心原因是PowerShell对SSH命令的解析逻辑导致。
原因分析
PowerShell会对命令中的双引号和反斜杠做额外解析:
- 双引号被PowerShell视为字符串边界,导致sed表达式被提前截断;
- 反斜杠作为PowerShell的转义字符被消耗,传递到远程主机时丢失,导致sed无法识别正则表达式中的元字符。
解决方法
方法1:转义单引号包裹sed命令
用单引号包裹远程执行的sed命令,同时在PowerShell中用两个单引号转义(PowerShell单引号转义规则),确保远程主机收到完整的sed表达式:
pwsh -c "ssh root@161.97.108.95 -p 22 'sed ''s/#\?\(PasswordAuthentication\s*\).*$/\1 no/'' /etc/ssh/sshd_config'"
方法2:双重转义反斜杠
由于PowerShell会吃掉一层反斜杠,将sed表达式中的所有反斜杠替换为\\,确保传递到远程主机时保留原正则结构:
pwsh -c ssh root@161.97.108.95 -p 22 sed "s/#\\?\\(PasswordAuthentication\\s*\\).*$/\\1 no/" /etc/ssh/sshd_config
方法3:使用PowerShell Here-String
通过Here-String避免手动转义,直接编写完整的SSH命令:
$remoteCmd = @" ssh root@161.97.108.95 -p 22 'sed "s/#\?\(PasswordAuthentication\s*\).*$/\1 no/" /etc/ssh/sshd_config' "@ pwsh -c $remoteCmd
内容的提问来源于stack exchange,提问作者Tirsvad
相关产品推荐
相关产品推荐

