Archived Forum Post

Index of archived forum posts

Question:

Reading output from SSH command

Apr 01 '16 at 16:27

I am trying to run a backup script on my server. I want to follow the output from the command.

I have tried ChannelReceiveUntilMatchAsync and a task but the task always finishes a few seconds after it starts and that ends the backup script.

How can I execute the shell script and follow the output using?


Answer

So after much more trial and error I finally found something that works. I Wanted to put it here for all the others out there that asked this question

Here it is:

    Dim ssh As New Chilkat.Ssh()

    '  Any string automatically begins a fully-functional 30-day trial.
    Dim success As Boolean = ssh.UnlockComponent("Anything for 30-day trial")
    If (success <> True) Then
        Console.WriteLine(ssh.LastErrorText)
        Exit Sub
    End If

    '  Connect to an SSH server:
    Dim hostname As String
    Dim port As Integer

    Dim cmdOutput As String

    '  Hostname may be an IP address or hostname:
    hostname = "*** your server ip ***"
    port = 22

    success = ssh.Connect(hostname, port)
    If (success <> True) Then
        Invoke(New DelegateUpdateCommandProgress(AddressOf UpdateCommandProgress), ssh.LastErrorText)
        Console.WriteLine(ssh.LastErrorText)
        Exit Sub
    End If

    '  Wait a max of 5 seconds when reading responses..
    ssh.EnableEvents = True

    ssh.IdleTimeoutMs = 2000
    '  Authenticate using login/password:
    success = ssh.AuthenticatePw("username", "your password")
    If (success <> True) Then
        Invoke(New DelegateUpdateCommandProgress(AddressOf UpdateCommandProgress), ssh.LastErrorText)
        Console.WriteLine(ssh.LastErrorText)
        Exit Sub
    End If

    '  Open a session channel.  (It is possible to have multiple
    '  session channels open simultaneously.)
    Dim channelNum As Integer
    channelNum = ssh.OpenSessionChannel()
    If (channelNum < 0) Then
        Console.WriteLine(ssh.LastErrorText)
        Exit Sub
    End If

    Dim termType As String = "dumb"
    Dim widthInChars As Integer = 180
    Dim heightInChars As Integer = 40
    '  Use 0 for pixWidth and pixHeight when the dimensions
    '  are set in number-of-chars.
    Dim pixWidth As Integer = 0
    Dim pixHeight As Integer = 0
    success = ssh.SendReqPty(channelNum, termType, widthInChars, heightInChars, pixWidth, pixHeight)
    If (success <> True) Then
        Invoke(New DelegateUpdateCommandProgress(AddressOf UpdateCommandProgress), ssh.LastErrorText)
        Console.WriteLine(ssh.LastErrorText)
        Exit Sub
    End If

    '  Start a shell on the channel:
    success = ssh.SendReqShell(channelNum)
    If (success <> True) Then
        Console.WriteLine(ssh.LastErrorText)
        Exit Sub
    End If
    Console.WriteLine("Shell Requested")

    '  Get a directory listing:
    Dim cmd As String = "<full path to your command>" + vbLf

    success = ssh.ChannelSendString(channelNum, cmd, "ansi")
    If (success <> True) Then
        Console.WriteLine("ssh.ChannelSendString" + ssh.LastErrorText)
        Exit Sub
    End If

    ssh.IdleTimeoutMs = 2000

    Dim n = ssh.ChannelReadAndPoll(channelNum, 250)

    If (success <> True) Then
        Console.WriteLine("task.run" + ssh.LastErrorText)
        Exit Sub
    End If
    Console.WriteLine("task started")
    While n > 0
        ssh.ChannelRead(channelNum)
        cmdOutput = ssh.GetReceivedText(channelNum, "ansi")

        If cmdOutput.Contains("JOBDONE") Then
            Console.WriteLine("Task Finished")
            Exit While
        End If

        Console.WriteLine(cmdOutput)
        Invoke(New DelegateUpdateCommandProgress(AddressOf UpdateCommandProgress), cmdOutput)

    End While

    ssh.ChannelSendClose(channelNum)

    ssh.Disconnect()

I am running this in a background thread. I created a Delegate that updates the text box.

At the end of my script I echo out JOBDONE and look for this in the command output on each poll. I tried using ChannelReceiveUntilMatch but it would never work right.

This isn't complete and could use more error checking etc but the basics are there.


Answer

This is a good article/response to read to get a better understanding of SSH automation: http://www.chilkatforum.com/questions/1272/understanding-ssh-automation

In a nutshell, your application is replacing a human at a terminal. I think conceptually understanding the application's role as SSH client should help in understanding what needs to be done in any given case.