reading long-running commands from shellstream

Mar 13, 2013 at 3:56 PM
Hi all,

I have a problem with reading from the shellstream whenever I sent long-running commands

I need to search in zip-files. (first I unzip the file (unzip-command) to a specific directory, then I sent a search-command.)
These are time consuming commands, which do not always give an immediate result (find).
for some reason, I do not get the complete result back from the stream.

i.e. the unzip-command stops abruptly.
          ...
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_3288-021-10v_20130112055047.20130112055141.txt  
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_3288-021-13v_20130112055047.20130112055141.txt  
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_2618-021-25v_2013

          the last line should contain a normal filename.
i.e. the find-command has an unexpected beginning (sometimes even the end of the previous command) - or no input at all!
        0112235408.txt  
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_4761_20130112235006014.20130112235437.txt  
          infla0112235408.txt  
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_4761_20130112235006014.20130112235437.txt  
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_5531_20130112235006047.20130112235437.txt  
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_5051_20130112235006034.20130112235437.txt  
          inflating: /export/home/hydraadm/testjo/unzipped/HICM_CONV_4688_20130112235005088.20130112235508.txt  
        uv137676@/export/home/hydraadm % uv137676@/export/home/hydraadm % find /export/home/hydraadm/testjo/unzipped -name \*CONV_\* -type f -exec grep -il "en01" {} \; -print | egrep -i "tien" |  uniq

        /export/home/hydraadm/testjo/unzipped/HICM_CONV_TIEN_20130112180512085.20130112181337.txt
        /export/home/hydraadm/testjo/unzipped/HICM_CONV_TIEN_20130112220523041.20130112221507.txt
        /export/home/hydraadm/testjo/unzipped/HICM_CONV_TIEN_20130112060513014.20130112061206.txt
        /export/home/hydraadm/testjo/unzipped/HICM_CONV_TIEN_20130112110523034.20130112111337.txt
        /export/home/hydraadm/testjo/unzipped/HICM_CONV_TIEN_20130112120534004.20130112121309.txt
        ....


First I tried with Expect(_shellPrompt) & Expect(_shellPrompt, timeSpan)
Then I tried with ReadLine and ReadToEnd
=> With these methods, a lot of errors occured
With Read (see code below) I was able to get good results (for short-running commands).

I'm using VS 2012 & .Net framework 4 with the 2013.1.27 version of the Renci.SshNet.

Whenever the commands take a long time, like in the examples above. It seems that something is going wrong.
  • Is my code badly written? Does this cause my problem?
  • Or is there some issue in the ssh.net library?
Thanks in advance for your input and help.

Kind regards

Jo
        string _shellPrompt = "uv137676";
        const string TerminalName = "HydraGuiShellStream";
        const uint Columns = 120;
        const uint Rows = 60;
        const uint Width = 800;
        const uint Height = 600;
        const int WaitMilliSeconds = 500;
        const int ArrayBufferSize = 4096;
        const int ShellStreamBufferSize = 33554432; //2^25 (~33MB)
        
        private void Test()
        {
            ShellStream _shellStream = client.RenciSshClient.CreateShellStream(TerminalName, Columns, Rows, Width, Height, ShellStreamBufferSize);//ShellStreamBufferSize=33554432

            StreamReader _reader = new StreamReader(_shellStream, Encoding.ASCII, true);
            StreamWriter _writer = new StreamWriter(_shellStream, Encoding.ASCII) { AutoFlush = true };
            
            Read(_reader);//get & discard login information
            
            string unzipCommand = "unzip -o /pathToZipFile/UnitTest_Unzip_Find.zip -d /pathToZipFile/unzipped";
            string findCommand = "find /pathToZipFile/unzipped -name \\*CONV_\\* -type f -exec grep -il \"en01\" {} \\; -print | egrep -i \"tien\" |  uniq";
            string returnValue;
                        
            _writer.WriteLine(unzipCommand); 
            returnValue = Read(_reader);//if shellprompt is read or waited long enough (i>=60); continue with find
            
            _writer.WriteLine(unzipCommand); 
            returnValue = Read(_reader);
        }
        
        private string Read(StreamReader streamReader)
        {
            var buffer = new char[ArrayBufferSize];//4096-2048-1024
            var stringBuilder = new StringBuilder();
            int i = 1;

            _shellStream.Flush();
            streamReader.Read(buffer, 0, buffer.Length);
            AddBufferToString(stringBuilder, buffer);

            while (!stringBuilder.ToString().Contains(_shellPrompt) && i < 60)
            {
                _shellStream.Flush();
                int charactersRead = streamReader.Read(buffer, 0, buffer.Length);
                AddBufferToString(stringBuilder, buffer);

                if (charactersRead == 0) //&& streamReader.EndOfStream
                {
                    Thread.Sleep(WaitMilliSeconds);
                    i++;
                }
                else
                    i = 0;

                buffer = new char[ArrayBufferSize];
            }

            streamReader.DiscardBufferedData();

            var returnValue = stringBuilder.ToString();

            return returnValue;
        }

        private static void AddBufferToString(StringBuilder stringBuilder, IEnumerable<char> buffer)
        {
            var arr = buffer.Where(b => b != '\0').ToArray();
            stringBuilder.Append(arr);
        }
Mar 15, 2013 at 1:34 PM
After a lot more tests, I found that if I ran the 2 commands in separate shellstreams, and did not read the response from my unzip command (instead waited for 10 sec)
, everything works fine -> my searchcommand executed with the correct response.
this is a workaround. I did not found the underlying cause of why it goes wrong with the unzip command. (maybe too much data in too short of a period ? - zip contains ~8500 files)

kind regards
Mar 15, 2013 at 2:04 PM
Ok, so I tuned my unzip command in order not to show the output (unzip -qq ...) and this works fine within one shellstream.

Still, I feel like there is a bug lying behind the original problem.

kr