使用 SSH.NET SshClient.RunCommand 执行的命令 (.4gl) 失败并显示 "No such file or directory"

Command (.4gl) executed with SSH.NET SshClient.RunCommand fails with "No such file or directory"

我有一个 Web 服务,它使用 SSH.NET 在 Unix 机器上调用 shell 脚本。

如果我 运行 脚本正常,它工作正常,在 Informix DB 上正常工作。

只是一些背景:
我调用了一个执行 .4gl 的脚本(不能将其显示为它的业务知识)。

当我使用 SSH.NET 执行 g4l 时,它在日志中返回以下错误:

fglgo: error while loading shared libraries: libiffgisql.so: cannot open shared object file: No such file or directory
file_load ended: 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 得到的错误。
为什么会发生这种情况,我可以让谁正确执行脚本?

SshClient.RunCommand 在内部使用 SSH“exec”通道。默认情况下,它(理所当然地)不会为会话分配伪终端 (PTY)。因此,(可能)获得了一组不同的启动脚本。 And/or 根据 TERM 环境变量的 absence/presence,采用脚本中的不同分支。因此环境可能不同于交互式会话,您使用 SSH 客户端。

因此,在您的情况下,PATH 的设置可能不同;因此找不到共享对象。

要验证这是根本原因,请在您的 SSH 客户端中禁用伪终端分配。例如在 PuTTY 中,它是 Connection > SSH > TTY > Don't allocate a pseudo terminal。然后,转到 Connection > SSH > Remote command 并输入 g4l 命令。选中 Session > Close window on exit > Never 并打开会话。您应该得到相同的 "No such file or directory" 错误。


解决此问题的方法,按优先顺序排列:

  1. 修复脚本不依赖于特定环境。

  2. 修复您的启动脚本,为交互式和非交互式会话设置相同的PATH

  3. 如果命令本身依赖于特定的环境设置并且您无法修复启动脚本,则可以在命令本身中更改环境。那取决于远程系统的语法 and/or shell。在常见的 *nix 系统中,这有效:

     sshclients.RunCommand("PATH=\"$PATH;/path/to/g4l\" && sh ...");
    
  4. 另一种(不推荐)方法是强制为“exec”通道分配伪终端。

    虽然SSH.NET不支持这个。您将不得不在 .RunCommand 实现中修改其代码问题 SendPseudoTerminalRequest 请求(我没有对此进行测试)。

    您也可以尝试使用.CreateShell方法使用“shell”频道。对于它,SSH.NET确实支持伪终端分配。

    不过,使用伪终端自动执行命令会给您带来严重的副作用。例如参见 [​​=19=]


对于类似的问题,请参阅

看到 Informix-4gl 开发人员在过渡到 FourJs Genero 并使用其 Web 服务功能时提出的类似问题。我要问他们的问题是 "who owns the fglgo/fglrun process that the Genero Application Server has launched, where is it running from, and what is its environment"。如果需要,我将用一个简单的程序来说明...

MAIN 
    RUN "env > /tmp/myname.txt"
    RUN "who >> /tmp/myname.txt"
    RUN "pwd >> /tmp/myname.txt"
END MAIN   

... 并说与命令行中的程序 运行 进行比较。通常是像前面的配置答案那样的情况,以便在执行 4gl 程序之前正确设置环境。