PureBasic
PureBasic
SSH Parallel Remote Commands on Multiple Servers
See more SSH Examples
Shows how to execute a command in parallel on multiple servers.Chilkat PureBasic Downloads
IncludeFile "CkSsh.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; Executing a command on multiple servers simultaneously is straightforward.
; It's just a matter of using one SSH object per server..
ssh1.i = CkSsh::ckCreate()
If ssh1.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
ssh2.i = CkSsh::ckCreate()
If ssh2.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
ssh3.i = CkSsh::ckCreate()
If ssh3.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
port.i = 22
success = CkSsh::ckConnect(ssh1,"ssh-server1.com",port)
If success <> 1
Debug CkSsh::ckLastErrorText(ssh1)
CkSsh::ckDispose(ssh1)
CkSsh::ckDispose(ssh2)
CkSsh::ckDispose(ssh3)
ProcedureReturn
EndIf
; Authenticate using login/password:
success = CkSsh::ckAuthenticatePw(ssh1,"sshLogin1","sshPassword1")
If success <> 1
Debug CkSsh::ckLastErrorText(ssh1)
CkSsh::ckDispose(ssh1)
CkSsh::ckDispose(ssh2)
CkSsh::ckDispose(ssh3)
ProcedureReturn
EndIf
; Connect and authenticate with 2 more servers.
; For brevity, the success/failure won't be checked...
success = CkSsh::ckConnect(ssh2,"ssh-server2.com",port)
success = CkSsh::ckAuthenticatePw(ssh2,"sshLogin2","sshPassword2")
success = CkSsh::ckConnect(ssh3,"ssh-server3.com",port)
success = CkSsh::ckAuthenticatePw(ssh3,"sshLogin3","sshPassword3")
; Note: If we wanted, we could've used ConnectAsync and AuthenticatePwAsync
; to do the connecting and authenticating in parallel...
; The command to be run on each SSH server will sleep for 5 seconds,
; and then show the current system date/time.
cmd.s = "sleep 5; date"
; Start each command
ssh1Channel.i = CkSsh::ckQuickCmdSend(ssh1,cmd)
If ssh1Channel < 0
Debug CkSsh::ckLastErrorText(ssh1)
CkSsh::ckDispose(ssh1)
CkSsh::ckDispose(ssh2)
CkSsh::ckDispose(ssh3)
ProcedureReturn
EndIf
; For brevity, we're not checking the return values here:
ssh2Channel.i = CkSsh::ckQuickCmdSend(ssh2,cmd)
ssh3Channel.i = CkSsh::ckQuickCmdSend(ssh3,cmd)
; OK, at this point the command is running simultaneously on each server.
; Now collect the results of each command.
pollTimeoutMs.i = 50
numFinished.i = 0
channel.i
; Note: You would rewrite this code to use arrays.
ssh1Finished.i = 0
ssh2Finished.i = 0
ssh3Finished.i = 0
While numFinished < 3
; Check to see if anything has finished.
; QuickCmdCheck returns -1 if there are no errors and nothing else finished
; QuickCmdCheck returns -2 if there was an error (such as a lost connection)
; QuickCmdCheck returns a channel number if a channel finished.
If ssh1Finished <> 1
channel = CkSsh::ckQuickCmdCheck(ssh1,pollTimeoutMs)
If channel = -2
Debug CkSsh::ckLastErrorText(ssh1)
CkSsh::ckDispose(ssh1)
CkSsh::ckDispose(ssh2)
CkSsh::ckDispose(ssh3)
ProcedureReturn
EndIf
If channel = ssh1Channel
Debug "---- ssh1 channel " + Str(channel) + " finished ----"
Debug CkSsh::ckGetReceivedText(ssh1,channel,"ansi")
numFinished = numFinished + 1
ssh1Finished = 1
EndIf
EndIf
If ssh2Finished <> 1
channel = CkSsh::ckQuickCmdCheck(ssh2,pollTimeoutMs)
If channel = -2
Debug CkSsh::ckLastErrorText(ssh2)
CkSsh::ckDispose(ssh1)
CkSsh::ckDispose(ssh2)
CkSsh::ckDispose(ssh3)
ProcedureReturn
EndIf
If channel = ssh2Channel
Debug "---- ssh2 channel " + Str(channel) + " finished ----"
Debug CkSsh::ckGetReceivedText(ssh2,channel,"ansi")
numFinished = numFinished + 1
ssh2Finished = 1
EndIf
EndIf
If ssh3Finished <> 1
channel = CkSsh::ckQuickCmdCheck(ssh3,pollTimeoutMs)
If channel = -2
Debug CkSsh::ckLastErrorText(ssh3)
CkSsh::ckDispose(ssh1)
CkSsh::ckDispose(ssh2)
CkSsh::ckDispose(ssh3)
ProcedureReturn
EndIf
If channel = ssh3Channel
Debug "---- ssh3 channel " + Str(channel) + " finished ----"
Debug CkSsh::ckGetReceivedText(ssh3,channel,"ansi")
numFinished = numFinished + 1
ssh3Finished = 1
EndIf
EndIf
Wend
; --------------
; Sample output:
; ---- ssh2 channel 101 finished ----
; Fri Dec 23 00:25:48 UTC 2016
;
; ---- ssh3 channel 102 finished ----
; Thu Dec 22 18:25:12 CST 2016
;
; ---- ssh1 channel 100 finished ----
; Thu Dec 22 18:25:48 CST 2016
CkSsh::ckDispose(ssh1)
CkSsh::ckDispose(ssh2)
CkSsh::ckDispose(ssh3)
ProcedureReturn
EndProcedure