Sample code for 30+ languages & platforms
B4X

SSH Parallel Remote Commands on Multiple Servers

See more SSH Examples

Demonstrates running the same command on several servers simultaneously. It is simply a matter of using one Ssh object per server, starting the command on each with QuickCmdSend, and then polling each connection with QuickCmdCheck until all have finished.

Background: This is the fan-out pattern behind configuration-management and monitoring tools: query or update a whole fleet in roughly the time the slowest single host takes, rather than the sum of all of them. Each server needs its own object because each has its own connection and authentication state. Note that results come back in whatever order the servers finish, which is why the example tracks completion per connection. Production code would keep the objects in arrays instead of repeating the logic per server.

Chilkat B4X Downloads

B4X
Dim success As Boolean = False

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

'  Demonstrates running the same command on several servers simultaneously.  It is simply a
'  matter of using one Ssh object per server.

Dim ssh1 As ChilkatSsh
ssh1.Initialize("ssh1")
Dim ssh2 As ChilkatSsh
ssh2.Initialize("ssh2")
Dim ssh3 As ChilkatSsh
ssh3.Initialize("ssh3")

Dim port As Int = 22

'  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.
Dim password As String = "mySshPassword"

success = ssh1.Connect("ssh-server1.example.com", port)
If success = False Then
    Log(ssh1.LastErrorText)
    Return
End If

success = ssh1.AuthenticatePw("mySshLogin", password)
If success = False Then
    Log(ssh1.LastErrorText)
    Return
End If


success = ssh2.Connect("ssh-server2.example.com", port)
If success = False Then
    Log(ssh2.LastErrorText)
    Return
End If

success = ssh2.AuthenticatePw("mySshLogin", password)
If success = False Then
    Log(ssh2.LastErrorText)
    Return
End If


success = ssh3.Connect("ssh-server3.example.com", port)
If success = False Then
    Log(ssh3.LastErrorText)
    Return
End If

success = ssh3.AuthenticatePw("mySshLogin", password)
If success = False Then
    Log(ssh3.LastErrorText)
    Return
End If


'  This command sleeps for 5 seconds and then prints the system date/time, making the parallel
'  execution easy to observe.
Dim cmd As String = "sleep 5; date"

'  Start the command on each server.  QuickCmdSend returns immediately.
Dim channel1 As Int = ssh1.QuickCmdSend(cmd)
If channel1 < 0 Then
    Log(ssh1.LastErrorText)
    Return
End If


Dim channel2 As Int = ssh2.QuickCmdSend(cmd)
If channel2 < 0 Then
    Log(ssh2.LastErrorText)
    Return
End If


Dim channel3 As Int = ssh3.QuickCmdSend(cmd)
If channel3 < 0 Then
    Log(ssh3.LastErrorText)
    Return
End If


'  The command is now running on all three servers at once.  Poll each connection until every
'  command has finished.  (Production code would keep the objects in arrays rather than
'  repeating the logic.)
Dim pollTimeoutMs As Int = 50
Dim numFinished As Int = 0
Dim finished1 As Boolean = False
Dim finished2 As Boolean = False
Dim finished3 As Boolean = False

Do While numFinished < 3
    If Not(finished1) Then
        Dim ch1 As Int = ssh1.QuickCmdCheck(pollTimeoutMs)
        If ch1 = -2 Then
            Log(ssh1.LastErrorText)
            Return
        End If

        If ch1 >= 0 Then
            Log("---- ssh1 channel " & ch1 & " finished ----")
            Dim out1 As String = ssh1.GetReceivedText(ch1, "utf-8")
            If ssh1.LastMethodSuccess = False Then
                Log(ssh1.LastErrorText)
                Return
            End If

            Log(out1)
            finished1 = True
            numFinished = numFinished + 1
        End If

    End If


    If Not(finished2) Then
        Dim ch2 As Int = ssh2.QuickCmdCheck(pollTimeoutMs)
        If ch2 = -2 Then
            Log(ssh2.LastErrorText)
            Return
        End If

        If ch2 >= 0 Then
            Log("---- ssh2 channel " & ch2 & " finished ----")
            Dim out2 As String = ssh2.GetReceivedText(ch2, "utf-8")
            If ssh2.LastMethodSuccess = False Then
                Log(ssh2.LastErrorText)
                Return
            End If

            Log(out2)
            finished2 = True
            numFinished = numFinished + 1
        End If

    End If


    If Not(finished3) Then
        Dim ch3 As Int = ssh3.QuickCmdCheck(pollTimeoutMs)
        If ch3 = -2 Then
            Log(ssh3.LastErrorText)
            Return
        End If

        If ch3 >= 0 Then
            Log("---- ssh3 channel " & ch3 & " finished ----")
            Dim out3 As String = ssh3.GetReceivedText(ch3, "utf-8")
            If ssh3.LastMethodSuccess = False Then
                Log(ssh3.LastErrorText)
                Return
            End If

            Log(out3)
            finished3 = True
            numFinished = numFinished + 1
        End If

    End If

Loop

ssh1.Disconnect
ssh2.Disconnect
ssh3.Disconnect