在 ssh 配置中强制使用 shell

在 ssh 配置中强制使用 shell

Match exec ...在 .ssh/config 中使用了一些规则。 (具体来说,我根据我的 IP 地址更改我的 ProxyJump)。在手册页中它解释了

exec 关键字在用户的 shell 下执行指定的命令。如果命令返回零退出状态,则条件被视为 true。包含空白字符的命令必须用引号引起来。

我使用两个语法相当不同的 shell(zsh 和 xonsh),这使得编写一个在这两个 shell 上同样有效的 exec 语句变得很困难。有没有办法强制 ssh 将 exec 命令传递到特定的 shell,而不是使用用户的 shell?

请注意,这是使用本地 shell 执行的,与远程服务器上运行的 shell 无关。

2021年9月9日编辑:

这里有更多细节。我的 ssh 配置中有以下内容:

match !exec "ifconfig | egrep -q 'inet (123\.45\.|67\.89\.)'"
    ProxyJump hop

这是 bash 语法。单引号强制解释原始字符串,因此斜杠被传递给egrep。

在 xonsh 中,由于 python 字符串引用规则,此语法是非法的。我必须使用r'123\.'禁用引用。请注意,我无法通过在 exec 命令内调用不同的 shell 来解决此问题,因为字符串引用仍然由外部 shell 执行,这可能会根据 $SHELL 的当前值而改变。

答案1

我一直无法找到一种方法来从 ssh 配置文件中强制使用特定的 shell。我相信唯一的选择是选择一个 shell 并确保任何启动 ssh 的方式设置$SHELL正确。

这可以通过几种方式来实现。对于这些示例,我假设我的 ssh_config 使用 bash 语法,并且我想从 xonsh 调用它,但应该同样可以使用不兼容 shell 的任意组合。

包装脚本

一种方法是在早期添加一个包装脚本,PATH以正确设置 SHELL:

〜/ bin / ssh:

#!/bin/bash
# Set the shell to use within .ssh/config
SHELL=/bin/bash exec /usr/bin/ssh "$@"

然后使其可执行(chmod +x ~/bin/ssh)。

~/.xonshrc 或您的调用 shell 的配置文件:

# Prepend to PATH
$PATH = p`~/bin` + $PATH

.ssh/config对于任何使用的工具(例如 sshuttle、sshfs 等)都必须执行此操作。

Xonsh 别名

对于我的 xonsh 特定解决方案,我使用了别名函数。

〜/.xonshrc:

def bash_shell(cmd):
    import functools
    def alias(cmd, args):
        with __xonsh__.env.swap(SHELL="/bin/bash"):
            ![@(cmd) @(args)]
    return functools.partial(alias, cmd)
aliases |= {
    'ssh': bash_shell('ssh'),
    'sshuttle': bash_shell('sshuttle'),
    # ...
}

相关内容