PowerShell事件驱动子程中SSH运行失败,-n选项生效原因及最优性咨询
PowerShell事件动作中SSH调用失败的原因与-n选项的作用
先澄清:是小写-n,不是大写-N
你提到的生效选项是小写-n,和大写-N完全不同:
- 大写
-N:确实是"不执行远程命令",仅用于建立SSH隧道 - 小写
-n:SSH的标准选项,作用是强制将标准输入(stdin)重定向到/dev/null(Windows下对应NUL),让SSH完全不尝试读取本地输入流
为什么事件动作里调用SSH会失败
PowerShell通过Register-ObjectEvent注册的-Action代码块,运行在无交互的后台运行空间中:
- 这个环境没有关联终端,标准输入(stdin)处于关闭状态,无法读取
- SSH默认会尝试读取本地stdin(哪怕你用了密钥认证不需要输入密码),当它发现stdin不可用时,会抛出错误或直接终止连接,导致命令执行失败
而直接在命令行执行时,stdin关联着你的终端,SSH可以正常读取(哪怕实际没内容),所以不会出问题。
为什么-n能解决问题
-n选项强制SSH跳过对stdin的读取操作,完全不依赖本地输入流。这样在无stdin的后台运行空间中,SSH就不会因为尝试读取无效的输入而报错,能正常完成远程命令的执行。
是否是最优解决方案
-n是针对这个场景的最优解决方案之一,理由如下:
- 它是SSH原生提供的选项,专门适配无交互、无stdin的运行环境(比如Windows服务、后台脚本、事件动作)
- 用法简单,只需要在ssh命令后追加
-n即可,不需要修改PowerShell事件的运行逻辑 - 性能开销极小,只是跳过了stdin读取的步骤
替代方案可以考虑:
- 用
Start-Process ssh -ArgumentList "-n user@host 'linux_command parameters'" -NoNewWindow -Wait,但本质还是依赖-n选项 - 重定向SSH的stdin到NUL:
ssh user@host "linux_command" < NUL,效果和-n一致,但写法不如-n简洁
内容的提问来源于stack exchange,提问作者chris vandert
相关产品推荐
相关产品推荐

