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

后端 未结 2 1055
失恋的感觉
失恋的感觉 2021-01-07 12:29

I have a web service that uses SSH.NET to call a shell script on a Unix box.

If I run the script normally, it works fine, does its work correctly on the Informix DB.

相关标签:
2条回答
  • 2021-01-07 13:13

    Have seen similar questions asked by Informix-4gl developers as they transition to FourJs Genero and using its Web Services functionality. The question I'll put to them is "who owns the fglgo/fglrun process that the Genero Application Server has launched, where is it running from, and what is its environment". If needed, I'll illustrate with a simple program that does something like ...

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

    ... and say compare with when program is running from command line. It is normally a case like in the earlier answer of configuring so that the environment is set correctly before the 4gl program is executed.

    0 讨论(0)
  • 2021-01-07 13:23

    The SshClient.RunCommand uses SSH "exec" channel internally. It, by default, (rightfully) does not allocate a pseudo terminal (PTY) for the session. As a consequence a different set of startup scripts is (might be) sourced. And/or different branches in the scripts are taken, based on absence/presence of the TERM environment variable. So the environment might differ from the interactive session, you use with your SSH client.

    So, in your case, the PATH is probably set differently; and consequently the shared object cannot be found.

    To verify that this is the root cause, disable the pseudo terminal allocation in your SSH client. For example in PuTTY, it's Connection > SSH > TTY > Don't allocate a pseudo terminal. Then, go to Connection > SSH > Remote command and enter your g4l command. Check Session > Close window on exit > Never and open the session. You should get the same "No such file or directory" error.


    Ways to fix this, in preference order:

    1. Fix the scripts not to rely on a specific environment.

    2. Fix your startup scripts to set the PATH the same for both interactive and non-interactive sessions.

    3. If the command itself relies on a specific environment setup and you cannot fix the startup scripts, you can change the environment in the command itself. Syntax for that depends on the remote system and/or the shell. In common *nix systems, this works:

       sshclients.RunCommand("PATH=\"$PATH;/path/to/g4l\" && sh ...");
      
    4. Another (not recommended) approach is to force the pseudo terminal allocation for the "exec" channel.

      Though SSH.NET does not support this. You would have to modify its code issue SendPseudoTerminalRequest request in .RunCommand implementation (I didn't test this).

      You can also try to use "shell" channel using .CreateShell method. For it, SSH.NET does support pseudo terminal allocation.

      Though, using the pseudo terminal to automate a command execution can bring you nasty side effects. See for example 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?


    For a similar issues, see

    • Renci SSH.NET - no result string returned for opmnctl
    • Certain Unix commands fail with "... not found", when executed through Java using JSch
    • Commands executed using JSch behaves differently than in SSH terminal (bypasses confirm prompt message of "yes/"no")
    • JSch: Is there a way to expose user environment variables to "exec" channel?
    0 讨论(0)
提交回复
热议问题