![如何让 shell 脚本在我通过 SSH 连接的所有地方都可用](https://linux22.com/image/1266626/%E5%A6%82%E4%BD%95%E8%AE%A9%20shell%20%E8%84%9A%E6%9C%AC%E5%9C%A8%E6%88%91%E9%80%9A%E8%BF%87%20SSH%20%E8%BF%9E%E6%8E%A5%E7%9A%84%E6%89%80%E6%9C%89%E5%9C%B0%E6%96%B9%E9%83%BD%E5%8F%AF%E7%94%A8.png)
我有一个我根本离不开的 shell 脚本:来自 Theiling Online 的酒吧
我经常在各种 *nix 服务器上使用 SSH。但是,我不是系统管理员,通常没有时间或权限在我连接的每台服务器上安装它。
它显然是一个非常可移植的sh
脚本,并具有将自身导出为 shell 函数的命令行选项,这让我开始思考:我是否可以使用 OpenSSH 的一个主观模糊功能将其导出到任何地方?
我的第一个想法是将源分配给一个环境变量BAR = "cat -v"
,然后在另一端将其作为“$BAR”执行,但是 1)我甚至无法让 cat 示例在本地工作,2)我不知道如何将脚本的实际多行源放入环境变量中,3)我还没有看到PermitUserEnvironment
启用此功能的机器。
我想我甚至可以使用 ssh 选项来写入在登录时调用的文件~/bar
,但更不稳定的解决方案会更好。
登录时拨打wget http://.../bar
电话是不可接受的。
有任何想法吗?
PS Putty 专用解决方案(尽管我怀疑是否存在)也很好。
编辑:我不想使用 wget 和其他基于文件的解决方案的原因是我不想留下痕迹,因为有时我会以其他人的用户或 root 身份进行连接。我也不希望我连接的每个服务器都发出 HTTP 请求。我希望这尽可能减少开销。
答案1
我没有尝试过任何这些,但您可以通过多种选项组合找到您想要的东西。
检查man 5 ssh_config
一下:
SendEnv
- 您可以将 bar 存储到环境变量中,但随后需要执行它。例如BAR=$(bar -D)
,然后在远程 shell 中eval $BAR
,将变量发送过去 - 我知道这离您想要的还差一步,但嘿,进步了;LocalCommand
- 不确定是否有帮助,除非您可以进行无人值守的 ssh,但那样的话我也看不到它能正常工作;
我看到的唯一其他选择是侵入客户端的源代码并引入一项功能,该功能在登录后立即执行命令(例如eval $BAR
,这可能是例如ssh_config
调用的选项RemoteCommand
),在发送环境变量之后和等待用户输入之前。
...
事实上我对完整答案有一个想法(未经测试):
在 中SendEnv
,确保发送PS1
和DEFINEBAR
,并设置PS1
为eval $DEFINEBAR
($DEFINEBAR 应包含您的函数,然后将 PS1 设置为合理值)。需要注意的是,服务器需要配置为接受环境变量,而对于默认或安全设置,这种情况不太可能发生。因此,如果您的设置不允许这样做,请回到原点。
答案2
这是 Dennis Williamson 解决方案的一个变体,它不需要您能够从远程计算机通过 ssh 返回到本地计算机。在本地系统上:
$ bar -D | ssh user@host 'cat > barfunc'
$ ssh user@host
在远程系统上:
$ . ./barfunc
我测试了它的组件但没有使用bar
,因为我没有。
答案3
在您的问题中,您说使用 wget 是不可接受的。您是反对使用 wget 还是反对复制文件?我认为,除非您以某种方式将文件复制到本地计算机,否则您将无法获得所需的功能。
也许您可以获取文件(但我相当确定这会失败)。该命令将如下所示,具体取决于 shell:
source mymachine:/home/user/bar
. mymachine:/home/user/bar
如果您特别反对 wget,您可以尝试 scp,设置 ssh 密钥意味着无密码体验。
mkdir ~/bin; scp -r myserver:/home/user/bin/* ~/bin; chmod u+x ~/bin
就我个人而言,对我有用的方法是将我的 shell 脚本放入 subversion 存储库,然后在每台机器上检出存储库。如果我更新了脚本,我可以在 svn 中重新检查它,然后在其他机器上更新它。
答案4
这也许可以给你一个开始:
在您的本地系统上:
$ bar -D > ~/barfunc
$ ssh user@host # or similar
在远程系统上:
$ func=$(scp yourname@yoursystem:~/barfunc /dev/stdout)
$ eval "$func"
$ bar_cat somefile ...