【问题标题】:Is it possible to run a program from terminal and have it continue to run after you close the terminal?是否可以从终端运行程序并在关闭终端后继续运行?
【发布时间】:2012-02-20 15:34:58
【问题描述】:

我编写了一个程序,我在通过 SSH 连接到盒子后运行该程序。它有一些用户交互,例如在提示后选择选项,通常我在注销之前等待它执行的过程完成,这会关闭终端并结束程序。但是现在这个过程很长,我不想在登录时等待,那么我该如何在 C 中实现这个解决方法呢?

【问题讨论】:

  • 为什么是“在 C 中”?为什么 Perl 中的解决方案不好? ??
  • 我希望将所有代码保留在用 C 编码的实际程序本身中。

标签: c linux


【解决方案1】:

你可以在后台运行一个程序,在命令后面加“&”

wget -m www.google.com &

或者,您可以使用“屏幕”程序,它允许您附加-分离会话

屏幕 wget -m www.google.com

(按 CTRL+D)

screen -r(重新附加)

http://linux.die.net/man/1/screen

【讨论】:

  • 所以,如果我像 ./program 这样运行程序,我仍然可以像往常一样与程序交互,但是当我关闭终端时,即使在注销后它仍然在后台运行?
  • 不,如果你用“&”运行程序,它会被打到后台,但仍然输出到终端——但是你将无法与之交互。关闭终端后它将继续工作。对于您所描述的内容,我绝对建议使用“屏幕” - 它非常有用。
  • 所以你的意思是它不能接受用户输入,但你可以让它报告它在做什么,例如?
  • 完全正确 - 使用屏幕,您可以像往常一样与它进行交互......将其视为 GUI 术语中的最小化窗口。您可以通过重新附加来恢复它,它会继续在后台运行,即使您结束会话(只要您将其分离)。
  • 当我关闭终端时,我的程序也关闭了。
【解决方案2】:

当 shell 退出时,进程会收到 HUP 信号。您所要做的就是安装一个忽略 SIGHUP 的信号处理程序。

或者只是使用 nohup 运行程序。

【讨论】:

  • 如何使用 nohup 运行程序?这对与 shell 中的程序的交互有任何负面影响吗?谢谢
  • 语法是“nohup command arguments &”。含义包括将程序输出写入名为 nohup.out 的文件 - 除非您将其重定向到不同的文件 - 并且 stdin 未连接到终端。
  • 哦,但是你的程序是交互式的。在这种情况下,您需要屏幕。
【解决方案3】:

执行此操作的传统方法是使用 nohup(1) 命令:

nohup mycmd < /dev/null >& output.log &

当然,如果您不关心输出,您也可以将其发送到 /dev/null,或者您可以根据需要从文件中获取输入。

这样做可以保护您的进程免受通常会导致它退出的 SIGHUP 的影响。您还需要像上面那样重定向标准输入/标准输出/标准错误,因为您将结束您的 ssh 会话。

上面显示的语法适用于 bash。

【讨论】:

  • 很遗憾,您将无法与该程序进行交互。
  • 没错——我最初错过了问题的那一部分。但是,如果交互以可预测的方式发生,则可以将用户输入放入文件中,并将文件重定向到标准输入。
【解决方案4】:

你可以使用 screen 命令。 here is a tutorial。请注意,您可能需要将其安装到您的系统中。

【讨论】:

    【解决方案5】:

    有很多选项 :-) TIMTOWTDI... 但是,出于您的目的,您可能会考虑运行命令行实用程序,例如 dtach 或 GNU screen

    如果你真的想在 C 中实现某些东西,你可以重新发明那个轮子,但从你对问题的描述来看,我怀疑它应该是必要的......

    【讨论】:

    • 老实说,我很想从 C 中实现解决方案,而不是依赖于盒子上的现有程序。
    【解决方案6】:

    后台进程的实际 C 代码是微不足道的:

    //do interactive stuff...  
    if(fork())
         exit(0);
    //cool, I've been daemonized.
    

    如果您知道代码永远不会在非 linux 或 BSD 机器上结束,您甚至可以使用 daemon()

    //interactive...
    daemon(0, 0);
    //background...
    

    【讨论】:

    • 真的那么简单吗?所以我可以在我的程序结束时拥有它,我可以退出终端,同时它仍在后台执行进程(没有进一步的输出/输入打印)?
    • 更好的解决方案是调用daemon函数。
    • 确实如此。你甚至可以测试它:main(){int k = getchar(); printf("%c\n", k); if(fork()) exit(0); pause(); } 然后关闭终端,然后ps ax | grep a.out。它会像白天一样清晰。
    • @BasileStarynkevitch daemon() 不是 POSIX
    • 但是问题是标记Linux,daemon是Linux提供的。
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2022-08-24
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2019-01-04
    相关资源
    最近更新 更多