【问题标题】:How can I run a dotnet application in the background using sudo on Linux?如何在 Linux 上使用 sudo 在后台运行 dotnet 应用程序?
【发布时间】:2018-09-03 21:35:46
【问题描述】:

我遇到了一些奇怪的问题,我不确定如何解决。我正在使用 CodeDeploy 将我的应用程序部署到 AWS EC2 实例,我需要在其中指定一个脚本来在我的实例上执行进程,其中一个是 .NET Core 应用程序。

我在 Windows 上使用 dotnet publish 发布我的应用程序,并将所需的 dll 复制到 EC2 Linux 实例。

我可以很好地运行应用程序,并且它的行为符合预期

sudo dotnet application.dll

但这只是在我终止应用程序并且不在后台之前。

当我尝试在后台运行我的应用程序时出现问题,以便我可以继续运行其他应用程序或执行其他任务。

我通常使用screennohup 在后台运行应用程序,但它似乎不适用于此应用程序。 screen 在脚本中不起作用,nohup 运行应用程序,但抛出错误

要使用 nohup 运行,我使用的是 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 F:\Applications\Server\Program.cs:line 38

现在我可以看到为什么会出现这种情况,因为错误中的路径是我在 Windows 上的项目的路径,但为什么只使用 nohup 会发生这种情况?如果我在前台运行它并且不抛出错误,这工作正常。

如何在不使用屏幕的情况下在后台运行此应用程序?


编辑

我最初的想法是因为它是在 Windows 上构建的,所以这是一些兼容性问题,但事实并非如此。我已将项目移至 Linux 实例并在那里重新发布,但在运行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

我刚试过

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

这似乎可以正常运行程序,但是每当执行另一个命令时,后台应用程序就会进入STOPPED 状态并且不会继续运行。

[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

下一步将研究在分离模式下使用screen

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

此命令当前不生成屏幕窗口...

编辑

我不得不在最后删除&,现在它可以按预期工作了。

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

【问题讨论】:

    标签: linux .net-core nohup


    【解决方案1】:

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

    启动 dotnet yourdll.dll

    启动 /b dotnet yourdll.dll

    在 Linux 上

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

    或者

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

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

    【讨论】:

    • 只运行 'nohup dotnet myapp.dll' 可以在没有 '> /dev/null 2>&1 &' 的情况下自行运行'> /dev/null 2>&1 &' 部分呢? ----编辑:没关系,只是发现了一些说它基本上会丢弃所有控制台输出的东西。我所做的将输出记录在某处。
    • > /dev/null 2>&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 信号关闭控制台应用程序。

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 2015-04-25
        • 2021-07-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多