locked
Wait till command is completely executed RRS feed

  • Question

  • User-73514677 posted

    Hi.

    I am trying to execute command prompt lines after connecting to remote unix server from a C# code. I have used the below code and which is working. However, I want the commands to execute completely before the next command line is taken. currently the execution of lines is faster and due to this, the result which I am getting is wrong.

    Each command should complete the processing and then move to next command. In my C# web application, I have the below code on a button click event

      SshClient sshclient = new SshClient(hostname, username, pwd);
      sshclient.Connect();
      ShellStream stream = sshclient.CreateShellStream("cmsd", 80, 24, 800, 600, 1024);

    objclass.sendCommand("command1", stream).ToString(); objclass.sendCommand("command2", stream).ToString();

    The class file contains the methods as below

    public StringBuilder  sendCommand(string customCMD, ShellStream stream)
            {
                StringBuilder answer = new StringBuilder();
                answer.Clear();
                var reader = new StreamReader(stream);
                var writer = new StreamWriter(stream);
                writer.AutoFlush = true;
                WriteStream(customCMD, writer, stream);
                answer = ReadStream(reader);
                return answer;           
            }    
    
            private void WriteStream(string cmd, StreamWriter writer, ShellStream stream)
            {
                writer.WriteLine(cmd);
                while (stream.Length == 0)
                {
                    Thread.Sleep(500);
                }
            }
    
            private StringBuilder ReadStream(StreamReader reader)
            {
                StringBuilder result = new StringBuilder();
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    result.AppendLine(line);
                }
                return result;
            }

    How to wait till first command is completely executed and then move to next command ?

    Thanks

    Wednesday, March 13, 2019 7:03 AM

All replies

  • User-1509636757 posted

    ShellStream stream = sshclient.CreateShellStream("cmsd", 80, 24, 800, 600, 1024);

    You may wait for bash prompt with 

    while (!stream.DataAvailable)
        System.Threading.Thread.Sleep(200);

    Reference: https://csharp.hotexamples.com/examples/Renci.SshNet/SshClient/RunCommand/php-sshclient-runcommand-method-examples.html

    Wednesday, March 13, 2019 11:51 AM
  • User475983607 posted

    venkatzeus

    How to wait till first command is completely executed and then move to next command ?

    First, this question has nothing to do with ASP.NET.  

    Basically, the interaction with the shell is the same as if you typed in the commands yourself.  Let's say you type a command.  I image you look at the screen and read the response.  Then depending on the response, you type the next command.  Correct? 

    I assume you are able to read the response stream at least your code is written to return the response stream.    So the question goes back to you.  Why are you ignoring the response?  And if you do get a response, what are you looking for exactly?  Is the problem that you need to return every response to the browser?

    Wednesday, March 13, 2019 12:09 PM
  • User-73514677 posted

    Hi Kaushal.

    Is this correct ?

       public StringBuilder sendCommand(string customCMD, ShellStream stream)
            {
                StringBuilder answer = new StringBuilder();
                answer.Clear();
                answer.Length = 0;            
    
                var reader = new StreamReader(stream);
                var writer = new StreamWriter(stream);
                writer.AutoFlush = true;
    
                while (!stream.DataAvailable)
                {
                    WriteStream(customCMD, writer, stream);
                    Thread.Sleep(5000);
                }
    
                answer = ReadStream(reader);
             
                return answer;
    
            }

    Yes, I need to wait for the prompt to move to next empty prompt and then read the data and show in browser UI

    Thanks

    Wednesday, March 13, 2019 2:00 PM
  • User475983607 posted

    IMHO, Thread.Sleep() is a troubleshooting step not a solution.  It allows time for the receive buffer to get populated.  That assume your code actually works.  Have you tested your code?  Did you write this code or did you copy it from somewhere and are not sure how it works?

    venkatzeus

    Yes, I need to wait for the prompt to move to next empty prompt and then read the data and show in browser UI

    Then your design is very far off the mark.   SignalR is or XHR is required to get the response from the unix command, through the web server, and to the browser.

    Wednesday, March 13, 2019 2:20 PM
  • User-73514677 posted

    Hi.

    With the existing original code, I am getting the response and able to show in browser, however there are few commands which take a longer time to execute and my code is not waiting for the completion and then showing the response. The problem is in here.

    After each command is added , i want to wait till the command is processed / completed / a new line is shown and then read the data and move to the next command

    Thanks

    Wednesday, March 13, 2019 2:25 PM
  • User475983607 posted

    With the existing original code, I am getting the response and able to show in browser, however there are few commands which take a longer time to execute and my code is not waiting for the completion and then showing the response. The problem is in here.

    After each command is added , i want to wait till the command is processed / completed / a new line is shown and then read the data and move to the next command

    Please read the link provided by  kaushalparik27.  

    https://csharp.hotexamples.com/examples/Renci.SshNet/SshClient/RunCommand/php-sshclient-runcommand-method-examples.html

    The link illustrates many different ways to use the 3rd party SslClient API. Perhaps use a callback.

    Wednesday, March 13, 2019 4:29 PM
  • User36583972 posted


    Hi venkatzeus,

    I am trying to execute command prompt lines after connecting to remote unix server from a C# code. I have used the below code and which is working. However, I want the commands to execute completely before the next command line is taken. currently the execution of lines is faster and due to this, the result which I am getting is wrong.


    You can try to use the Asynchronous Methods in ASP.NET 4.5.

    For example: When you wait the command1 completely and receive the result. You can check the command1 result and executes the command2.

    During an asynchronous call, a thread is not blocked from responding to other requests while it waits for the request to complete. So, it will not block the UI thread.

    Using Asynchronous Methods in ASP.NET 4.5
    https://docs.microsoft.com/en-us/aspnet/web-forms/overview/performance-and-caching/using-asynchronous-methods-in-aspnet-45


    Best Regards

    Yong Lu

    Thursday, March 14, 2019 2:31 AM
  • User-73514677 posted

    Hi..

    I can see that when the command ends and a new line is shown the characters [a  is shown

    Is it possible to wait or read to find [a  is the start characters and then move to next line ? How to achieve this in the below code?

     public StringBuilder sendCommand(string customCMD, ShellStream stream)
            {
                StringBuilder answer = new StringBuilder();
                answer.Clear();
                answer.Length = 0;
    
                var reader = new StreamReader(stream);
                var writer = new StreamWriter(stream);
                writer.AutoFlush = true;
                          
                WriteStream(customCMD, writer, stream);
                 answer = ReadStream(reader);      
                return answer;
    
            }
    
            private void WriteStream(string cmd, StreamWriter writer, ShellStream stream)
            {
                writer.WriteLine(cmd);
                while (stream.Length == 0)
                {
                    Thread.Sleep(2000);
                }
            }
    
            private StringBuilder ReadStream(StreamReader reader)
            {
                StringBuilder result = new StringBuilder();
                result.Clear();
                result.Length = 0;
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    result.AppendLine(line);
                }
                return result;
            }

    Thanks

    Thursday, March 14, 2019 4:15 PM
  • User475983607 posted

    venkatzeus

    Hi..

    I can see that when the command ends and a new line is shown the characters [a  is shown

    Is it possible to wait or read to find [a  is the start characters and then move to next line ? How to achieve this in the below code?

     public StringBuilder sendCommand(string customCMD, ShellStream stream)
            {
                StringBuilder answer = new StringBuilder();
                answer.Clear();
                answer.Length = 0;
    
                var reader = new StreamReader(stream);
                var writer = new StreamWriter(stream);
                writer.AutoFlush = true;
                          
                WriteStream(customCMD, writer, stream);
                 answer = ReadStream(reader);      
                return answer;
    
            }
    
            private void WriteStream(string cmd, StreamWriter writer, ShellStream stream)
            {
                writer.WriteLine(cmd);
                while (stream.Length == 0)
                {
                    Thread.Sleep(2000);
                }
            }
    
            private StringBuilder ReadStream(StreamReader reader)
            {
                StringBuilder result = new StringBuilder();
                result.Clear();
                result.Length = 0;
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    result.AppendLine(line);
                }
                return result;
            }

    Thanks

    Your question infers that your code works?  Generally, a stream is defined as input/output and the same stream instance is used to send/receive data.  I've never reviewed code that splits a stream into a separate reader and writer instance for synchronous operations. 

    Anyway, the general approach in any IO process is send a command and wait for a response.  If the response can take many seconds and is this is synchronous IO, then simply read the response buffer in a loop until data shows up or the you timeout.

    I recommend that you contact support for the 3rd party SshClient API you are using or try reading the open code.  Also there is a lot of sample code for the SshClient that you can pull from.  As far as I can tell, there's methods that even wait for a pattern match.

    https://csharp.hotexamples.com/examples/Renci.SshNet/ShellStream/Expect/php-shellstream-expect-method-examples.html

    https://csharp.hotexamples.com/examples/Renci.SshNet/ShellStream/ReadLine/php-shellstream-readline-method-examples.html

    Perhaps try going through the sample code to find something that works for you.  

    Lastly, it is certainly possible to wait for any character.  Just place an "if" within a loop or use a while...loop which is a built-in "if".

    Thursday, March 14, 2019 5:39 PM
  • User-729763720 posted

    I was faced with the exact same problem. My workaround was to look for the remote machine prompt character at the end of the string returned by the SSH stream reader. Not the most elegant solution, but it worked for me, hope it works for you.

    Wednesday, September 11, 2019 3:29 PM