我有一个 Web 服务,它使用 SSH.NET 调用 Unix 机器上的 shell 脚本。
如果我正常运行该脚本,它工作正常,在 Informix DB 上正常工作。
只是一些背景:
我调用一个执行的脚本.4gl
(不能将此显示为其业务知识)。
当我使用 SSH.NET 执行 g4l 时,g4l 在日志中返回以下错误:
fglgo:加载共享库时出错:libiffgisql.so:无法打开共享对象文件:没有这样的文件或目录
文件加载结束:2017-09-21 15:37:01
执行 SSH.NET 脚本的 C# 代码
sshclients = new SshClient(p, 22, username, password);
sshclients.Connect();
sshclients.KeepAliveInterval = new TimeSpan(0, 0, 1);
sshclients.RunCommand("sh " + Script_dir);
我添加了KeepAliveInterval
,看看是否有帮助。
我的问题是我从 Unix/4gl 得到的错误。
为什么会发生这种情况?谁可以让脚本正确执行?
The SshClient.RunCommand
内部使用 SSH“exec”通道。默认情况下,它(正确地)不会为会话分配伪终端 (PTY)。因此,(可能)会获取一组不同的启动脚本。和/或根据不存在/存在,在脚本中采取不同的分支TERM
环境变量。因此,环境可能与您使用 SSH 客户端的交互式会话不同。
所以,就你的情况而言,PATH
可能设置不同;因此无法找到共享对象。
要验证这是否是根本原因,请在 SSH 客户端中禁用伪终端分配。例如在 PuTTY 中,它是连接 > SSH > TTY > 不分配伪终端。然后,前往连接 > SSH > 远程命令并输入您的g4l
命令。查看会话 > 退出时关闭窗口 > 从不并打开会话。你应该得到同样的“没有这样的文件或目录” error.
解决此问题的方法(按优先顺序排列):
-
修复脚本以使其不依赖于特定环境。
-
修复您的启动脚本以设置PATH
对于交互式和非交互式会话都是相同的。
-
如果命令本身依赖于特定的环境设置,并且您无法修复启动脚本,则可以在命令本身中更改环境。其语法取决于远程系统和/或 shell。在常见的 *nix 系统中,这是有效的:
sshclients.RunCommand("PATH=\"$PATH;/path/to/g4l\" && sh ...");
-
另一种(不推荐)方法是强制为“exec”通道分配伪终端。
尽管 SSH.NET 不支持这一点。您必须修改其代码问题SendPseudoTerminalRequest
请求在.RunCommand
实现(我没有测试这个)。
您还可以尝试使用“shell”通道.CreateShell
方法。对于它,SSH.NET确实支持伪终端分配。
不过,使用伪终端自动执行命令可能会给您带来令人讨厌的副作用。参见示例有没有一种简单的方法可以消除使用 Python 的 Paramiko 库进行 SSH 并从远程计算机的 CLI 获取输出时出现的垃圾值?
类似问题请参见
- Renci SSH.NET - 没有为 opmnctl 返回结果字符串
- 当使用 JSch 通过 Java 执行时,某些 Unix 命令会失败并显示“...未找到”
- 使用 JSch 执行的命令的行为与 SSH 终端不同(绕过确认提示消息“yes/”no”)
- JSch:有没有办法将用户环境变量公开给“exec”通道?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)