Sample code for 30+ languages & platforms
DataFlex

Read an SSH Channel Until Output Goes Quiet

See more SSH Examples

Demonstrates the Chilkat Ssh.ChannelReadAndPoll method, which reads a channel in two phases: it waits for the first channel message, then keeps processing until no further data arrives for the given number of milliseconds. The first argument is the channel number and the second is the second-phase poll timeout.

The integer return value is -1 on error, -2 if nothing arrived before the timeout, 0 if EOF or channel close was processed, or — when greater than 0 — the total bytes currently buffered for the channel (not the bytes newly received by this call).

Background: This solves the practical problem of "read everything the command produced" when the channel is not going to close — an interactive shell, for example, stays open after each command. Waiting for a quiet period is a pragmatic stand-in for an end-of-output marker. The initial wait is governed by ReadTimeoutMs (or IdleTimeoutMs when that is zero), while the argument controls only the quiet-period phase.

Chilkat DataFlex Downloads

DataFlex
Use ChilkatAx-win32.pkg

Procedure Test
    Boolean iSuccess
    Handle hoSsh
    Integer iSshPort
    String sPassword
    Integer iChannelNum
    Integer iPollTimeoutMs
    Integer iResult
    String sOutput
    String sTemp1
    Boolean bTemp1

    Move False To iSuccess

    //  Demonstrates the Ssh.ChannelReadAndPoll method, which reads a channel in two phases: it waits
    //  for the first channel message, then keeps processing until no more data arrives for the given
    //  number of milliseconds.  The 1st argument is the channel number and the 2nd is the poll
    //  timeout for the second phase.

    Get Create (RefClass(cComChilkatSsh)) To hoSsh
    If (Not(IsComObjectCreated(hoSsh))) Begin
        Send CreateComObject of hoSsh
    End

    Move 22 To iSshPort
    Get ComConnect Of hoSsh "ssh.example.com" iSshPort To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  Normally you would not hard-code the password in source.  You should instead obtain it
    //  from an interactive prompt, environment variable, or a secrets vault.
    Move "mySshPassword" To sPassword

    Get ComAuthenticatePw Of hoSsh "mySshLogin" sPassword To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Get ComOpenSessionChannel Of hoSsh To iChannelNum
    If (iChannelNum < 0) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  Start a shell WITHOUT requesting a PTY.  Without a PTY the shell sees it is connected to a
    //  raw data pipe and enters non-interactive mode: it suppresses the command prompt, does not
    //  echo typed commands back, and skips interactive login scripts.  The output is therefore
    //  clean and easily parseable -- but because no prompt is ever sent, code must not wait for
    //  one.  Instead, have each command print a predictable marker, or wait for EOF / channel close.
    Get ComSendReqShell Of hoSsh iChannelNum To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Get ComChannelSendString Of hoSsh iChannelNum "ls -l /usr/bin" + (character(10)) "utf-8" To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  Keep reading until the output goes quiet for 500 milliseconds.
    Move 500 To iPollTimeoutMs
    //  The return value is: -1 on error, -2 if nothing arrived before the timeout, 0 if EOF or
    //  channel close was processed, or the total number of buffered bytes when greater than 0.
    Get ComChannelReadAndPoll Of hoSsh iChannelNum iPollTimeoutMs To iResult
    If (iResult = -1) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    If (iResult = -2) Begin
        Showln "No channel data arrived before the timeout."
    End

    If (iResult = 0) Begin
        Showln "EOF or channel close was processed.  Buffered data may still remain."
    End

    If (iResult > 0) Begin
        Showln "Total bytes buffered: " iResult
    End

    Get ComGetReceivedText Of hoSsh iChannelNum "utf-8" To sOutput
    Get ComLastMethodSuccess Of hoSsh To bTemp1
    If (bTemp1 = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Showln sOutput

    Send ComDisconnect To hoSsh


End_Procedure