使用 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" 错误。
解决此问题的方法,按优先顺序排列:
修复脚本不依赖于特定环境。
修复您的启动脚本,为交互式和非交互式会话设置相同的PATH
。
如果命令本身依赖于特定的环境设置并且您无法修复启动脚本,则可以在命令本身中更改环境。那取决于远程系统的语法 and/or shell。在常见的 *nix 系统中,这有效:
sshclients.RunCommand("PATH=\"$PATH;/path/to/g4l\" && sh ...");
另一种(不推荐)方法是强制为“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 程序之前正确设置环境。
我有一个 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" 错误。
解决此问题的方法,按优先顺序排列:
修复脚本不依赖于特定环境。
修复您的启动脚本,为交互式和非交互式会话设置相同的
PATH
。如果命令本身依赖于特定的环境设置并且您无法修复启动脚本,则可以在命令本身中更改环境。那取决于远程系统的语法 and/or shell。在常见的 *nix 系统中,这有效:
sshclients.RunCommand("PATH=\"$PATH;/path/to/g4l\" && sh ...");
另一种(不推荐)方法是强制为“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 程序之前正确设置环境。