Question:
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?
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.
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.