DataFlex
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
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