How can I run a dotnet application in the background using sudo on Linux?

时间:2018-03-25 18:51:24

标签: linux .net-core nohup

I am experiencing some weird problems that I'm not sure how to solve. I am using CodeDeploy to deploy my applications to an AWS EC2 instance, and in there I need to specify a script to execute the processes on my instances, one of which is a .NET Core application.

I am publishing my application using dotnet publish on Windows, and copying the required dlls to the EC2 Linux instance.

I can run the application fine using and this behaves as expected

sudo dotnet application.dll

However this is simply until I terminate the application and is not in the background.

The problem is happening when I am trying to run my application in the background, so that I can continue running other applications or perform other tasks.

I usually use screen or nohup to run applications in the background however it doesn't seem to work for this application. Screen doesn't work in the script, and nohup runs the application, but throws an error

To run using nohup I am using sudo nohup dotnet application.dll & and I receive the error in the log

Unhandled Exception: System.UnauthorizedAccessException: Access to the path is denied. ---> System.IO.IOException: Bad file descriptor
   --- End of inner exception stack trace ---
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Interop.CheckIo(Int64 result, String path, Boolean isDirectory, Func`2 errorRewriter)
   at System.ConsolePal.Read(SafeFileHandle fd, Byte[] buffer, Int32 offset, Int32 count)
   at System.ConsolePal.UnixConsoleStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadLine()
   at System.IO.SyncTextReader.ReadLine()
   at System.Console.ReadLine()
   at Application.Program.Main(String[] args) in F:\Applications\Server\Program.cs:line 38

Now I can see why this is thrown, as the path in the error is the path to my project on Windows, but why is this happening only using nohup? This works fine if I run it in the foreground and does not throw the error.

How can I run this application in the background without using screen?


EDIT

My initial thought was that is was some compatibility issue as it was built on Windows, however this is not the case. I have moved the project over to the Linux instance and re-published it there, and I am still receiving the same error when running sudo nohup dotnet application.dll &

 Unhandled Exception: System.UnauthorizedAccessException: Access to the path is denied. ---> System.IO.IOException: Bad file descriptor
   --- End of inner exception stack trace ---
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Interop.CheckIo(Int64 result, String path, Boolean isDirectory, Func`2 errorRewriter)
   at System.ConsolePal.Read(SafeFileHandle fd, Byte[] buffer, Int32 offset, Int32 count)
   at System.ConsolePal.UnixConsoleStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadLine()
   at System.IO.SyncTextReader.ReadLine()
   at System.Console.ReadLine()
   at Application.Program.Main(String[] args) in /opt/servers/Server/Program.cs:line 38

I have just tried

sudo dotnet application.dll > out.log 2>&1 &

which seems to run the program without error, however whenever another command is performed, the background application is sent into a STOPPED state and does not continue to run.

[1]+ Stopped sudo dotnet application.dll > out.log 2>&1

ubuntu@:/opt/servers/Server$ sudo dotnet application.dll > out.log  2>&1 &
[1] 2448
ubuntu@:/opt/servers/Server$ netstat -tulpn
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
udp   214656      0 0.0.0.0:1000            0.0.0.0:*                           -
udp        0      0 0.0.0.0:68              0.0.0.0:*                           -
udp        0      0 0.0.0.0:68              0.0.0.0:*                           -

[1]+  Stopped                 sudo dotnet application.dll > out.log 2>&1

Next step would be to look into using screen in detached mode.

screen -d -m bash -c 'cd /opt/server && sudo dotnet application.dll &'

This command currently doesn't spawn a screen window...

EDIT

I had to remove the & at the end and now it works as expected.

screen -d -m -S SERVER bash -c 'cd /opt/server && sudo dotnet application.dll'

3 个答案:

答案 0 :(得分:3)

如果它在Windows上(我不确定你是否需要它),只需运行start,它将基本上运行async。示例(前景和背景)

  

启动dotnet yourdll.dll

     

start / b dotnet yourdll.dll

在Linux上

  

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

或者

  

nohup dotnet yourapp.dll> / dev / null 2>& 1&

并且,您的上面的屏幕命令(您可以分离/附加到)

答案 1 :(得分:2)

对我来说,问题是:

Console.ReadKey();

我已将代码替换为:

var cancellationTokenSource = new CancellationTokenSource();
AppDomain.CurrentDomain.ProcessExit += (s, e) => cancellationTokenSource.Cancel();
Console.CancelKeyPress += (s, e) => cancellationTokenSource.Cancel();
await Task.Delay(-1, cancellationTokenSource.Token).ContinueWith(t => { });

使用此代码,您可以使用CTRL + C或SIGTERM信号关闭控制台应用程序。

希望这会有所帮助!

答案 2 :(得分:0)

以前的解决方案对我来说不起作用,因为消息侦听器无法接收消息,因此在主程序的最后一行中,我用Thread.Sleep(Timeout.Infinite)替换了Console.ReadLine()。这就解决了nohup问题,日志记录问题并在后台运行。 我不记得我必须用Java来做这些事情来阻止Tibco或Rabbit消息监听器。