如何使用nohup在Mono中执行进程?

时间:2015-07-21 15:59:27

标签: c# linux mono sh nohup

我正在寻找在Linux机器中执行Mono(C#)的进程,但我需要它在我的.exe退出后继续运行。我正在尝试使用nohup来做到这一点,但到目前为止还没有取得任何成功。这是我现在的代码:

void Execute(string command, string commandPath, string arguments, bool nohup = false)
{
   ProcessStartInfo startInfo = new ProcessStartInfo()
                        {
                            FileName = nohup ? "sh" : Path.Combine(commandPath, script),
                            Arguments = nohup ? "nohup " + Path.Combine(commandPath, script) + " " + arguments + " &" : arguments,
                            UseShellExecute = false,
                            CreateNoWindow = true,
                            RedirectStandardOutput = true,
                            RedirectStandardError = true,
                            RedirectStandardInput = true,
                            UserName = System.Environment.UserName
                        };

        using (Process process = Process.Start(startInfo))
                        { // Monitor for exit}
}

所以我正在检查nohup参数,如果是,我执行shell并发送完整命令(例如:nohup /path/to/my/command <args> &)。我收到的错误是/path/to/my/command cannot execute binary file

我想到的另一件事是打开sh进程然后将完整的nohup命令发送到标准输入,但为了做到这一点,我必须重构相当多的代码,所以如果有办法没有这个我做我想要的,我会走那条路。

那么......在Linux环境(Mono)中使用nohup在父进程死后保持活着的C#中执行进程的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

  

我收到错误消息,指出/ path / to / my / command无法执行   二进制文件。

在这种情况下,我会将CreateNoWindow更改为true,不要重定向IO并查看您在创建的shell中获得的内容以便调试...

到目前为止正在创建一个后台进程,一种方法是创建守护进程并有一个方法来读取/写入信息(网络端口,文件日志等),但只是像你尝试工作一样启动后台任务精细。

这是一个使用您的代码作为起点的快速黑客/示例。而不是使用Process,我只是系统执行命令,在这种情况下是一个查找。由于它在后台运行,我运行一个进程来计算1秒后日志文件中的行数,并在退出时得到一个提示来终止该后台查找过程......

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Threading;

    namespace nohub.process.exec
    {
        class MainClass
        {

            [DllImport ("libc")]
            private static extern int system (string exec);

            private static string logfile = Path.GetTempFileName ();

            static void Execute (string command, string commandPath, string arguments, bool nohup = false)
            {
                if (!nohup) {
                    var startInfo = new ProcessStartInfo () {
                        FileName = Path.Combine (commandPath, command),
                        Arguments = arguments,
                        UseShellExecute = false,
                        CreateNoWindow = true,
                        RedirectStandardOutput = true,
                        RedirectStandardError = true,
                        RedirectStandardInput = true,
                        UserName = System.Environment.UserName
                    };

                    using (Process process = Process.Start (startInfo)) { // Monitor for exit}
                        process.WaitForExit ();
                        using (var output = process.StandardOutput) {
                            Console.Write ("Results: {0}", output.ReadLine ());
                        }
                    }
                } else {
                    system ("nohup " + Path.Combine (commandPath, command) + " " + arguments + " 2>&1 > " + logfile + " & "); 
                }

            }

            public static void Main (string[] args)
            {
                Console.WriteLine ("Hello Stack Overflow");
                Console.WriteLine ("Temp file: {0}", logfile);
                Execute ("find", "", "/", true);
                Thread.Sleep (1000);
                Execute ("wc", "", "-l " + logfile, false);
                Console.Write ("\nLet find continue? [y/n]");
                if ((Console.ReadKey (false)).KeyChar == 'y')
                    system ("killall find");
            }
        }
    }