C#使用进程调用bash,不断往bash内插入命令并执行

呃呃呃,遇到了一个非常恶心得问题,现在就是,有几十万条数据需要当作参数调用python脚本

一次一次输入命令过去缓慢,经过了多层考虑决定使用进程来解决(不知道线程怎么开启bash得)

原理非常简单,类似与打开一个cmd窗口不断地往cmd窗口内写入命令

参数如下:

bashCount:打开进程个数,也就是启动bash数量

command:命令

     public static void CreateBash(int bashCount, List<string> command)
        {
            try
            {
                var data = Convert.ToInt32(Math.Ceiling((double)command.Count / bashCount));
                Parallel.For(0, bashCount, (i) =>
                {
                    Process p = new Process();
                    //设置要启动的应用程序
                    p.StartInfo.FileName = "bash";
                    //是否使用操作系统shell启动
                    p.StartInfo.UseShellExecute = false;
                    // 接受来自调用程序的输入信息
                    p.StartInfo.RedirectStandardInput = true;
                    //输出信息
                    p.StartInfo.RedirectStandardOutput = true;
                    // 输出错误
                    p.StartInfo.RedirectStandardError = true;
                    //不显示程序窗口
                    p.StartInfo.CreateNoWindow = true;
                    //启动程序
                    p.Start();
                    var test = command.Skip(i * data).Take(data).ToArray();
                    var count = 0;
                    var commandStr = "";
                    var commandCount = Convert.ToInt32(Math.Ceiling((double)test.Count() / 10));
                    if (test.Count() > 0)
                    {

                        foreach (var item in test)
                        {
                            count++;
                            var filePath = item.Split(".").FirstOrDefault();
                 //执行命令
var demo= $"{Environment.CurrentDirectory.ToString()}/ScriptFile/ProAnalysis {item} {filePath}.pa 0"; var demo1 = $"{Environment.CurrentDirectory.ToString()}/ScriptFile/pcap2featuresjson {item} {filePath}.json {filePath}.bin {filePath}.hex"; commandStr += demo + ";" + demo1; commandStr += ";"; if (count >= 100) { p.StandardInput.WriteLine(commandStr); count = 0; commandStr = ""; } } } p.StandardInput.WriteLine("exit"); p.StandardInput.AutoFlush = true; string strOuput = p.StandardOutput.ReadToEnd(); p.WaitForExit(); p.Close(); }); } catch (Exception e) { Console.WriteLine("失败" + e.Message); } }

可以直接复用

详细讲解一下方法:Parallel.For让多个bash并行运行,并且每个取出相等的命令,往bash写入

补充一下,昨天写完这个方法去解决十几万条数据时候,发生了内存泄露问题,进经过排查问在进程参数设置,把输出错误输出信息都改为false,去掉

string strOuput = p.StandardOutput.ReadToEnd();
修改完毕后代码如下:
 public static void CreateBash(int bashCount, List<string> command)
        {
            var disCommand = command.Distinct().ToList();
            Console.WriteLine(disCommand.Count());
            try
            {
                var data = Convert.ToInt32(Math.Ceiling((double)disCommand.Count / bashCount));
                Parallel.For(0, bashCount, (i) =>
                {
                    Process p = new Process();
                    //设置要启动的应用程序
                    p.StartInfo.FileName = "bash";
                    //是否使用操作系统shell启动
                    p.StartInfo.UseShellExecute = false;
                    // 接受来自调用程序的输入信息
                    p.StartInfo.RedirectStandardInput = true;
                    //输出信息
                    p.StartInfo.RedirectStandardOutput = false;
                    // 输出错误
                    p.StartInfo.RedirectStandardError = false;
                    //不显示程序窗口
                    p.StartInfo.CreateNoWindow = true;
                    //启动程序
                    p.Start();
                    var test = disCommand.Skip(i * data).Take(data).ToArray();
                    var commandCount = (int)Math.Ceiling((double)test.Count() / 10);
                    if (test.Count() > 0)
                    {
                        var commandStr = "";
                        var count = 0;
                        foreach (var item in test)
                        {
                            count++;
                            var filePath = item.Split(".").FirstOrDefault();
                            var demo1 = $"{Environment.CurrentDirectory.ToString()}/ScriptFile/ProAnalysis {item} {filePath}.pa 0";
                            var demo2 = $"{Environment.CurrentDirectory.ToString()}/ScriptFile/pcap2featuresjson {item} {filePath}.json {filePath}.bin {filePath}.hex";
                            commandStr += demo1 + ";" + demo2;
                            commandStr += ";";
                            if (count >= commandCount)
                            {
                                p.StandardInput.WriteLine(commandStr);
                                count = 0;
                                commandStr = "";
                            }
                        }
                    }
                    p.StandardInput.WriteLine("exit");
                    p.StandardInput.AutoFlush = true;
                    p.WaitForExit();
                    p.Close();
                });
            }
            catch (Exception e)
            {
                Console.WriteLine("失败" + e.Message);
            }

        }
仅供参考方法,转载请标明出处,谢谢

posted @ 2022-04-26 16:55  薛小谦  阅读(435)  评论(5编辑  收藏  举报