使用SSH.NET SshClient.RunCommand执行的命令(.4gl)失败,并且#34;没有这样的文件或目录"

时间:2017-09-21 18:03:37

标签: c# linux ssh ssh.net 4gl

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

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

只是一些背景:
我调用一个执行.4gl的脚本(不能将此作为其商业知识)。

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

  

fglgo:加载共享库时出错:libiffgisql.so:无法打开共享对象文件:没有这样的文件或目录
  file_load结束: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得到的错误。
为什么会发生这种情况以及我可以让谁能正确执行脚本?

2 个答案:

答案 0 :(得分:0)

SshClient.RunCommand内部使用SSH“exec”频道。默认情况下,它(正确地)不会为会话分配伪终端(PTY)。因此,可能(可能)采购了一组不同的启动脚本。和/或脚本中的不同分支基于public class StringDecomposer { public String process(String input) { StringBuilder result = new StringBuilder(); decompres(input, 0, result); return result.toString(); } private int decompres(String input, int ofset, StringBuilder result) { StringBuilder rpt = new StringBuilder(); StringBuilder current = new StringBuilder(); while(ofset < input.length()) { if(input.charAt(ofset) == '[') { ofset = decompres(input, ofset+1, current); repeat(rpt, current); result.append(current); rpt.delete(0, rpt.length()); current.delete(0, current.length()); } else if(input.charAt(ofset) == ']') { break; } else if(input.charAt(ofset) > 47 && input.charAt(ofset) < 58) { rpt.append(input.charAt(ofset)); } else { current.append(input.charAt(ofset)); } ofset++; } result.append(current); return ofset; } private void repeat(StringBuilder rpt, StringBuilder input) { if(rpt.length() > 0) { StringBuilder current = new StringBuilder(input); int times = Integer.parseInt(rpt.toString()); for(int i = 1; i < times; i++) { input.append(current); } } } } 环境变量的缺失/存在而被采用。因此环境可能与交互式会话不同,您可以使用SSH客户端。

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

要验证这是根本原因,请在SSH客户端中禁用伪终端分配。例如,在PuTTY中,它是 Connection&gt; SSH&gt; TTY&gt;不要分配伪终端。然后,转到 Connection&gt; SSH&gt;远程命令并输入您的PATH命令。检查会话&gt;关闭退出窗口&gt;从不并打开会话。你应该得到相同的“没有这样的文件或目录”错误。

如何按优先顺序解决此问题:

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

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

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

    PATH
  4. 另一种(不推荐)方法是强制“exec”频道的伪终端分配。

    虽然SSH.NET不支持此功能。您必须在sshclients.RunCommand("PATH=\"$PATH;/path/to/g4l\" && sh ..."); 实施中修改其代码问题SendPseudoTerminalRequest请求(我没有对此进行测试)。

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

    尽管使用伪终端自动执行命令会带来令人讨厌的副作用。例如,请参阅Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?

  5. 有关类似问题,请参阅

答案 1 :(得分:0)

Informix-4gl开发人员在转换到FourJs Genero并使用其Web服务功能时遇到了类似的问题。我将向他们提出的问题是“谁拥有Genero Application Server已启动的fglgo / fglrun进程,它在哪里运行,以及它的环境是什么”。如果需要,我将用一个简单的程序来说明,它可以像......一样......

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

...并说明与程序从命令行运行时的比较。通常情况下,在早期的配置答案中,以便在执行4gl程序之前正确设置环境。