首页 > 解决方案 > OpenSSH 多平台配置 - 如何避免 Match exec 错误消息?

问题描述

我开始在 Windows、WSL2 和 Git for Windows 中使用具有相同配置的 OpenSSH 客户端。

在配置的某些地方,我需要基于平台的条件配置。目前我使用这样的部分~/.ssh/config

# Identity agent socket override for Windows
Match !exec "uname -o | grep -qE 'Linux|Msys'"
    IdentityAgent \\.\pipe\openssh-ssh-agent
Match exec "uname -o | grep -q 'Msys'"
    IdentityAgent /c/Users/username/tmp/cyglockfile

在具有命令的类 unix 环境中unamegrep它可以完美运行。在 Windows 上它可以工作(就像一个返回错误状态的现有命令),但我收到关于不存在命令的烦人错误消息:

PS C:\Users\username> ssh machine
'uname' is not recognized as an internal or external command,
operable program or batch file.
'uname' is not recognized as an internal or external command,
operable program or batch file.
'uname' is not recognized as an internal or external command,
operable program or batch file.
...

是否有选项可以隐藏Match exec不存在命令的错误消息?

我知道我可以创建自己的平台测试脚本,但我不想在所有环境中都维护它。

标签: windowscross-platformwindows-subsystem-for-linuxopenssh

解决方案


解决方案(我一直在使用的)

警告:请参阅下面的注释,包括要求

Match exec "dir c: 1>/dev/null 2>&1"
  IdentityFile c:/Users/YOURUSERNAMEDIR/.ssh/id_rsa
Match exec "dir /etc 1>/dev/null 2>&1"  
  IdentityFile /mnt/c/Users/YOURUSERNAMEDIR/.ssh/id_rsa

几点注意事项:

  • 要求:要完成这项工作,您必须创建文件夹 "C:\dev",因为默认情况下 Windows 上不存在 "/dev/null"。每次在 Windows 上使用 ssh 时,都会使用环境重写“null”文件。我通常通过文件资源管理器在属性中将此文件夹设置为“隐藏”,这样它就不会显示出来。
  • 此设计基于“Match exec”的限制:
    • 无论操作系统平台如何,所有“匹配执行”命令都将始终执行,如果返回 0,将使用任何缩进配置。因此它只允许两个“执行路径”(返回值 0 和返回值非 0)
    • “Match exec”使用 cmd shell 作为 Windows 10 上的默认 shell。我不确定是否有办法改变它,因为我们可以在 Linux(通过 env 的 bash)和 Windows(默认为powershell)
      • 在 cmd 和 bash 之间没有常见的重定向到“/dev/null”或“/tmp”的方法
    • 考虑到前两个事实,我们要运行两个“Match exec”检查。在这种情况下:
      • 前一个“Match exec”将在 Windows 上返回 0,在 Linux 上返回 1
      • 后者“Match exec”将在 Linux 上返回 0,在 Windows 上返回 1
  • “匹配”指令可以是任何顺序

替代解决方案

如果您为了“聪明”而牺牲清晰度,还有其他可能的解决方案。这些解决方案提供了卓越的性能,并且没有文件系统副产品。从理论上讲,这将允许您支持更多的操作系统(通过支持更多的 shell),但由于这些 shell 之间缺乏通用语法和不可预测的返回码,这不太可能。

例如,您可以以存在“默认”条件并利用“bashism”的方式对语句进行排序:


IdentityFile c:/Users/YOURUSERNAMEDIR/.ssh/id_rsa

Match exec "exit ${ONWINDOWS:=1}"
  IdentityFile /mnt/c/Users/YOURUSERNAMEDIR/.ssh/id_rsa

我过去曾使用过类似的东西,但我已经将它换成了阅读时更清楚的解决方案。

我在配置文件的评论中有以下链接作为源:https ://creechy.wordpress.com/2021/02/03/quest-for-a-multi-platform-ssh-config/


对于不存在的命令,是否可以隐藏 Match exec 的错误消息?

我对此没有答案。我一直想要这个特殊的功能。


作为旁注,我相信您尝试做的通常是由 ssh-agent 处理的。如:您在每个 Unix/Windows 系统上分别配置 ssh-agent 以默认使用一个或多个 SSH 密钥,因此“.ssh/config”中不需要引用但是,当要求比你的问题,这可能是你的情况。


推荐阅读