[Mono-list] shell comands and piping

Rampage atomikramp at email.it
Sat Aug 21 12:02:38 EDT 2010


Michael Hutchinson ha scritto:
> On Wed, Aug 18, 2010 at 8:49 PM, Rampage <atomikramp at email.it> wrote:
>   
>> Hello everyone,
>> i've browsed the archive but couldn't find any information about this,
>> so i hope you can help me out :)
>>
>> here is my problem:
>> i have a method like this:
>>
>>       public string StartProcess(string sProgram, string sArguments)
>>       {
>>           Process prc = new Process();
>>           prc.StartInfo.UseShellExecute = false;
>>           prc.StartInfo.FileName = sProgram;
>>           prc.StartInfo.Arguments = sArguments;
>>           prc.StartInfo.RedirectStandardOutput = true;
>>           prc.Start();
>>           string stdout;
>>           stdout = prc.StandardOutput.ReadToEnd();
>>           return stdout;
>>       }
>>
>> suppose that i run it like this:
>> StartProcess("cat", "testfile.txt");
>> i would get a string containing the output from cat.
>> the problem comes if i want to pipe something
>> generally using the shell i would do
>> #cat testfile.txt | grep word (i know i can do grep word testfile.txt,
>> but it's just for example)
>>
>> is there a way to use the pipe with forked processes? couse i can't pass
>> it as an argument for my program couse it wont work.
>>     
>
> Piping simply feeds the standard output of one process to the standard
> input of another. You could do this in C# by using
> Process.StandardInput.
>
> Alternatively, you could run a shell command using sh:
> StartProcess("sh", "-c 'cat testfile.txt | grep word' ");
>
> Best solution IMO would just be to use  .NET APIs, unless the shell
> commands are doing particularly complex thing:
> var txt = File.ReadAllText ("testfile.txt");
> var matches = Regex.Matches (txt, "word");
>
>   
Hi :)
Thanks for the reply,
i've tried doing as you said using standardinput like this:

--------------------------------------------------------------------------
        public string StartPipedProcess(string sProgram, string 
sArguments, string sStdin)
        {
            string stdout;

            Process prc = new Process();
            prc.StartInfo.UseShellExecute = false;
            prc.StartInfo.FileName = sProgram;
            prc.StartInfo.Arguments = sArguments;
            prc.StartInfo.RedirectStandardOutput = true;
            prc.StartInfo.RedirectStandardInput = true;

            prc.Start();

            StreamWriter sw = prc.StandardInput;

            do
            {
                if(sStdin.Length > 0)
                {
                    sw.Write(sStdin);
                }
            }

            while(sStdin.Length != 0);

            sw.Flush();
            sw.Close();

            stdout = prc.StandardOutput.ReadToEnd();
            return stdout;
        }

--------------------------------------------------------------------------

and then invoked an example command like this
StartPipedProcess("xxd", "-l 256", "teststringstandardinput");

but it returned me with this error:

--------------------------------------------------------------------------

ystem.Reflection.TargetInvocationException: Exception has been thrown by 
the target of an invocation. ---> System.IO.IOException: Write fault on 
path [Unknown]
  at System.IO.FileStream.FlushBuffer () [0x00000]
  at System.IO.FileStream.Flush () [0x00000]
  at System.IO.StreamWriter.Flush () [0x00000]
  at System.IO.StreamWriter.Write (System.String value) [0x00000]
  at VoodooToolkit.TSKProcess.StartPipedProcess (System.String sProgram, 
System.String sArguments, System.String sStdin) [0x0005c] in 
/home/rampage/Projects/voodoo/trunk/VoodooToolkit/VoodooToolkit/TSK/TSKProcess.cs:58 

  at MainWindow.OnSelectionChanged (System.Object sender, 
System.EventArgs e) [0x00064] in 
/home/rampage/Projects/voodoo/trunk/VoodooToolkit/VoodooToolkit/MainWindow.cs:216 

  at (wrapper managed-to-native) 
System.Reflection.MonoMethod:InternalInvoke 
(object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, 
BindingFlags invokeAttr, System.Reflection.Binder binder, 
System.Object[] parameters, System.Globalization.CultureInfo culture) 
[0x00000]
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, 
BindingFlags invokeAttr, System.Reflection.Binder binder, 
System.Object[] parameters, System.Globalization.CultureInfo culture) 
[0x00000]
  at System.Reflection.MethodBase.Invoke (System.Object obj, 
System.Object[] parameters) [0x00000]
  at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x00000]
  at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) 
[0x00000]
  at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000]
  at GLib.Signal.ClosureInvokedCB (System.Object o, 
GLib.ClosureInvokedArgs args) [0x00000]
  at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x00000]
  at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr 
return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr 
invocation_hint, IntPtr marshal_data) [0x00000]
   at GLib.ExceptionManager.RaiseUnhandledException(System.Exception e, 
Boolean is_terminal)
   at GLib.SignalClosure.MarshalCallback(IntPtr raw_closure, IntPtr 
return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr 
invocation_hint, IntPtr marshal_data)
   at Gtk.Application.gtk_main()
   at Gtk.Application.Run()
   at VoodooToolkit.MainClass.Main(System.String[] args) in 
/home/rampage/Projects/voodoo/trunk/VoodooToolkit/VoodooToolkit/Main.cs:line 
78
--------------------------------------------------------------------------

too bad i cant get it to work properly.

Thanks for the help



More information about the Mono-list mailing list