Sample code for 30+ languages & platforms
DataFlex

SSH ChannelReceiveUntilMatchN (Match Any of Several Prompts)

See more SSH Examples

Demonstrates ChannelReceiveUntilMatchN, which receives until any one of several patterns is matched. This is useful when driving an interactive session where the shell prompt differs from device to device.

Note: This example deliberately requests a PTY. Matching a shell prompt only works in an interactive session — without a PTY the shell runs non-interactively and never prints a prompt at all. For scripted use, omit the PTY and match on a marker your own command echoes.

Background: Real sessions have more than one possible next output, so waiting for one specific string risks hanging when something else appears. Matching a set lets the code proceed on whichever actually occurs — a user prompt, a root prompt, or a device-specific one. A "dumb" terminal type is requested so the remote side does not mix ANSI escape sequences into the output, which would otherwise complicate matching. Remember that retrieving text clears the receive buffer; leaving a prompt buffered would make the next receive match immediately and return the wrong output.

Chilkat DataFlex Downloads

DataFlex
Use ChilkatAx-win32.pkg

Procedure Test
    Boolean iSuccess
    Handle hoSsh
    Variant vSaPrompts
    Handle hoSaPrompts
    String sHostname
    Integer iPort
    String sPassword
    Integer iChannelNum
    String sTermType
    Integer iWidthInChars
    Integer iHeightInChars
    Integer iPixWidth
    Integer iPixHeight
    Boolean iCaseSensitive
    String sCmdOutput
    String sTemp1
    Boolean bTemp1

    Move False To iSuccess

    //  This example requires the Chilkat API to have been previously unlocked.
    //  See Global Unlock Sample for sample code.

    //  Demonstrates ChannelReceiveUntilMatchN, which receives until ANY one of several patterns is
    //  matched.  This is useful when driving an interactive session where the shell prompt varies
    //  from device to device.
    //  
    //  Note: This example deliberately DOES request a PTY.  Matching a shell prompt only works in an
    //  interactive session -- without a PTY the shell runs non-interactively and never prints a
    //  prompt at all.  For scripted use where no prompt is needed, omit the PTY and match on a
    //  marker your own command echoes instead.

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

    //  The remote shell prompt may be any of these, depending on the device.
    Get Create (RefClass(cComCkStringArray)) To hoSaPrompts
    If (Not(IsComObjectCreated(hoSaPrompts))) Begin
        Send CreateComObject of hoSaPrompts
    End
    Get ComAppend Of hoSaPrompts "~$" To iSuccess
    Get ComAppend Of hoSaPrompts "mars#" To iSuccess
    Get ComAppend Of hoSaPrompts "jupiter%" To iSuccess
    Get ComAppend Of hoSaPrompts "chilkat$" To iSuccess
    Get ComAppend Of hoSaPrompts "admin>" To iSuccess

    Move "ssh.example.com" To sHostname
    Move 22 To iPort
    Get ComConnect Of hoSsh sHostname iPort 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

    //  Request a pseudo-terminal so the shell runs interactively and prints prompts.  A "dumb"
    //  terminal is used so that ANSI escape sequences are not mixed into the output.
    Move "dumb" To sTermType
    Move 120 To iWidthInChars
    Move 40 To iHeightInChars
    Move 0 To iPixWidth
    Move 0 To iPixHeight
    Get ComSendReqPty Of hoSsh iChannelNum sTermType iWidthInChars iHeightInChars iPixWidth iPixHeight To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Get ComSendReqShell Of hoSsh iChannelNum To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  IMPORTANT: Set a read timeout before receiving until a match.  ReadTimeoutMs defaults to 0,
    //  which means no limit -- without it, this call waits forever if the received data never
    //  contains a match.
    Set ComReadTimeoutMs Of hoSsh To 15000

    Move True To iCaseSensitive

    //  Read the initial login text up to the first prompt.
    Get pvComObject of hoSaPrompts to vSaPrompts
    Get ComChannelReceiveUntilMatchN Of hoSsh iChannelNum vSaPrompts "utf-8" iCaseSensitive To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

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

    Showln sCmdOutput

    //  ---- 1st command ----
    Get ComChannelSendString Of hoSsh iChannelNum "cd /tmp" + (character(10)) "utf-8" To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Get pvComObject of hoSaPrompts to vSaPrompts
    Get ComChannelReceiveUntilMatchN Of hoSsh iChannelNum vSaPrompts "utf-8" iCaseSensitive To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  Retrieving the text also clears the receive buffer, which matters: if a prompt were left
    //  buffered, the next receive would match it immediately and return the wrong output.
    Get ComGetReceivedText Of hoSsh iChannelNum "utf-8" To sCmdOutput
    Get ComLastMethodSuccess Of hoSsh To bTemp1
    If (bTemp1 = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Showln sCmdOutput

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

    Get pvComObject of hoSaPrompts to vSaPrompts
    Get ComChannelReceiveUntilMatchN Of hoSsh iChannelNum vSaPrompts "utf-8" iCaseSensitive To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

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

    Showln sCmdOutput

    //  Finish the session.
    Get ComChannelSendEof Of hoSsh iChannelNum To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Get ComChannelReceiveToClose Of hoSsh iChannelNum To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

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

    Showln sCmdOutput

    Send ComDisconnect To hoSsh


End_Procedure