【问题标题】:Proxying commands across a SSH connection通过 SSH 连接代理命令
【发布时间】:2017-10-05 01:16:50
【问题描述】:

我希望能够“欺骗”我机器上的某些命令,实际上是在远程系统上调用它们。例如。每当我跑步时:

cmd options

我希望实际的命令是:

ssh user@host cmd options

理想情况下,我希望有一个名为spoof 的文件夹,将其添加到我的PATH,并在其中有一个名为cmd 的可执行文件来进行欺骗。如果我有很多命令,这可能会变得乏味。任何人都有一个好的方法来解决这个问题?这样我将来可以添加和删除很多命令吗?而且,我希望能够准确(或尽可能准确地)传递所有参数,并且我想欺骗的每一个命令都只会在它前面有 ssh user@host

原因是我在我的机器上运行一个容器(特别是singularity),并且有些命令我真的不想容器化,但仍想在容器内运行。我发现我可以通过在它前面附加ssh 来获得我想要的功能。示例是 sbatchmatlab 容器化很痛苦,我可以只使用 ssh 调用它们。这些程序使用的文件被写入绑定点,因此主机可以正常查看它们。

【问题讨论】:

标签: linux bash unix ssh


【解决方案1】:

以下脚本可以硬链接到您希望透明代理的所有命令名称下:

#!/usr/bin/env bash
printf -v str '%q ' "${0##*/}" "$@"
ssh host "$str"
  • SSH 将其所有参数组合成一个字符串,然后由远程 shell 执行。为确保远程参数与本地参数相同,值需要转义;否则,somecommand "hello world"somecommand "hello" "world" 可以通过网络以相同方式表示。
  • 在适当扩展的printf(包括bash 和ksh 实现)中,%q 被替换为相应值的转义形式,该值将evaled 回到原始(文字)文本 if稍后解释。
  • printf -v varnameprintf 的输出存储在名为varname 的变量中,而不会产生命令替换的开销/效率低下。 (在 ksh93 中,varname=$(printf ...) 被优化为跳过 subshel​​l 开销,所以这不是必需的)。
  • $0 的计算结果为 argv[0],按照惯例,它是当前正在运行的命令的名称。 (这可以被覆盖,但您相信您的用户行为合理......对吗?)
  • ${0##*/} 是一个parameter expansion,它只返回$0 中最后一个/ 之后的内容(它实际上是否应该包含任何斜杠;否则,原始值未经修改使用)。
  • "$@" 指的是传递给脚本的确切参数向量。

【讨论】:

  • 我会测试一下。能稍微解释一下吗?
  • 初步测试表明这很好用。我需要再测试一些,但现在非常感谢。
  • 我已经为所有使用的语法添加了解释。如果有任何遗漏,请告诉我。
  • @Justin, ...btw, is 实际上是一个有点问题的地方——printf '%q' 可以生成只有在以下情况下才能正确转义的代码远程外壳与本地外壳匹配。如果您在本地使用 bash 而在远程使用 /bin/sh,则在传递带有换行符的字符串或其他内容 %q 使用 $'' 转义时可能会遇到一些麻烦。解决这个问题的简单方法是将bash -s 作为即时远程命令运行并将脚本文本传递到标准输入,但这意味着您的远程进程无法访问其原始标准输入。
  • @Justin, ...也可以让 Python 的 pipes.quote() 助手以独立于 shell 的方式为您进行引用;我想我已经在本网站的其他地方回答了有关如何做到这一点的问题。
猜你喜欢
  • 2016-08-20
  • 2013-10-10
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
相关资源
最近更新 更多