最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Run Bash commands in C# .Net Core from background app - Stack Overflow

programmeradmin1浏览0评论

our application consists in a service that is launched on a linux host, in particular a yocto linux custom embedded image.

Inside the app there are calls to some bash commands in order to change the system configuration, i.e. the date, the systemd network configuration, et similar.

To achieve this I used a RunCommand method with the following implementation:

 public static Result<string> RunCommand(string command, bool wait = true)
{
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return new Result<string>() { ResultObject = "done" };

     Result<string> result = new Result<string>();
     using (Process proc = new())
     {
         proc.StartInfo.FileName = "/bin/bash";
         proc.StartInfo.Arguments = "-c \" " + command + " \"";
         proc.StartInfo.UseShellExecute = true;
         proc.StartInfo.RedirectStandardOutput = true;
         proc.StartInfo.RedirectStandardError = true;
         proc.StartInfo.CreateNoWindow = true;
        
         proc.Start();
     
         proc.OutputDataReceived += Proc_OutputDataReceived;

         result.ResultObject = proc.StandardOutput.ReadToEnd();
         var error = proc.StandardError.ReadToEnd();
         if (!string.IsNullOrWhiteSpace(error))
         {
             result.HasError = true;
             result.ErrorMessage = error;
             result.ResultCode = Enums.ResultCode.UnspecifiedError;
         }
         if (wait)
             proc.WaitForExit();
         proc.OutputDataReceived -= Proc_OutputDataReceived;
     }
     return result;
}

Now, the issue. If I call the app directly, like ./Controller all works perfectly, but if I call the app in backround, like ./Controller &, then the app hangs forever. I assume it is due to output redirection, but I don't have enough knowledge nor I know where to look at to fix this...

our application consists in a service that is launched on a linux host, in particular a yocto linux custom embedded image.

Inside the app there are calls to some bash commands in order to change the system configuration, i.e. the date, the systemd network configuration, et similar.

To achieve this I used a RunCommand method with the following implementation:

 public static Result<string> RunCommand(string command, bool wait = true)
{
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return new Result<string>() { ResultObject = "done" };

     Result<string> result = new Result<string>();
     using (Process proc = new())
     {
         proc.StartInfo.FileName = "/bin/bash";
         proc.StartInfo.Arguments = "-c \" " + command + " \"";
         proc.StartInfo.UseShellExecute = true;
         proc.StartInfo.RedirectStandardOutput = true;
         proc.StartInfo.RedirectStandardError = true;
         proc.StartInfo.CreateNoWindow = true;
        
         proc.Start();
     
         proc.OutputDataReceived += Proc_OutputDataReceived;

         result.ResultObject = proc.StandardOutput.ReadToEnd();
         var error = proc.StandardError.ReadToEnd();
         if (!string.IsNullOrWhiteSpace(error))
         {
             result.HasError = true;
             result.ErrorMessage = error;
             result.ResultCode = Enums.ResultCode.UnspecifiedError;
         }
         if (wait)
             proc.WaitForExit();
         proc.OutputDataReceived -= Proc_OutputDataReceived;
     }
     return result;
}

Now, the issue. If I call the app directly, like ./Controller all works perfectly, but if I call the app in backround, like ./Controller &, then the app hangs forever. I assume it is due to output redirection, but I don't have enough knowledge nor I know where to look at to fix this...

Share Improve this question asked Mar 12 at 15:19 Marcomattia MocellinMarcomattia Mocellin 3906 silver badges17 bronze badges 6
  • What is the command ? , any feedback from the bash session ? , try sticking the command in a shell file and run that .... – ticktalk Commented Mar 18 at 14:08
  • I have many commands, i.e. "date" but also creating files with content and permissions... Also I have to get the IP address of a labelled interface (i have eth0 setup as DHCP client, and eth0:0 as static fallback ip). – Marcomattia Mocellin Commented Mar 19 at 14:40
  • #1 Usually c# apps are built as dll and then are executed with dotnet foo.dll . How are you building your app? – JRichardsz Commented Mar 22 at 12:56
  • Does the error occur with simple commands like : ls, date, ps -ef , etc ? – JRichardsz Commented Mar 22 at 13:00
  • I am publishing the app as an executable file, so it's called straight like Controller [args]. – Marcomattia Mocellin Commented Mar 25 at 9:39
 |  Show 1 more comment

1 Answer 1

Reset to default 0

Solution

Use nohup command

nohup ./Controller >/dev/null 2>&1 &

#1 If you want to see the output I suggested you to use a log file

Explanation

The problem could be related to these lines

if (wait)
    proc.WaitForExit();

And the usage of the ampersand &.

According to this answer, one of the differences between ampersand and nohup is that if you close the shell, the process started with ampersand will be terminated while the one started with nohup will continue executing.

As a result, this sentence never ends: proc.WaitForExit()

Test with ampersand

Using this code I tried with ampersand and as was expected, it hangs for ever

dotnet run date &

Test with nohup

nohup dotnet run date >/dev/null 2>&1 &

The process is started immediately, shell exits and in the background the command is executed and does its job.

References

  • https://stackoverflow/a/53882651/3957754
发布评论

评论列表(0)

  1. 暂无评论