春江593 2025-08-23 12:36 采纳率: 90%
浏览 4
已结题

fg命令使用中的一处疑问

最近在工作中使用fg命令时发现一处不理解的地方:
在终端中输入top&,然后显示 [1] 2556,没有问题,该任务在后台运行。
然后我输入jobs,希望计算机显示所有后台任务情况,但输出“[1]+ 已停止 top”。此时我并未中止top任务,为何会自动停止?
随后我输入 fg 1,希望将其调到前台继续运行,但却输出:
top
top: failed tty set: 被中断的系统调用
这其中的原因是什么?

对比曾经学习过的另一个命令:sleep 100
输入#sleep 100&
输出:[2] 3035 程序正常在后台运行
输入#jobs
显示:[2]+ 运行中 sleep 100 &
输入#fg 2
显示 :sleep 100 程序又回到前台继续运行
这个过程我就可以理解,但为何top命令与此不同?

非常感谢各位!

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-08-23 12:37
    关注

    中午好🌞🌞🌞
    本答案参考通义千问

    你提出的问题非常具有代表性,涉及 fg 命令后台进程(Job Control) 的行为差异。我们来详细分析你遇到的两个命令(topsleep)在使用 fg 时的不同表现,并解释其中的原因。


    📌 问题总结

    你执行了以下操作:

    top &
    

    输出为:

    [1] 2556
    

    接着执行:

    jobs
    

    输出为:

    [1]+ 已停止 top
    

    然后执行:

    fg 1
    

    输出为:

    top: failed tty set: 被中断的系统调用
    

    而使用 sleep 100 时却没有类似问题。


    🔍 问题核心:为什么 top 在后台运行后会“停止”,而 sleep 不会?

    ✅ 关键原因:终端交互性程序(如 top)与非交互性程序(如 sleep)的区别

    1. top 是一个交互式程序

    • top 是一个需要与终端进行交互的程序,它通过读取终端输入(如按键)来控制显示。
    • 当你将 top 放入后台(top &),它会尝试从终端获取输入,但由于它现在处于后台,无法正常访问终端设备
    • 因此,shell 会自动将其挂起(stopped),以防止它试图访问终端导致错误。

    2. sleep 是一个非交互式程序

    • sleep 是一个简单的延时程序,不需要与终端交互
    • 它可以在后台运行而不会出现问题,也不会被 shell 自动挂起。

    ⚙️ 为什么 fg 会报错?

    当你执行 fg 1 时,shell 会尝试将该作业(即 top恢复到前台运行,并重新分配其对终端的访问权限。

    但此时,top 已经被挂起(stopped),并且它的终端状态可能已经损坏或不一致。因此,在将其恢复到前台时,top 会尝试重新设置终端属性(如窗口大小、输入模式等),但因为某些原因(如终端未正确连接或被其他进程占用),这个操作失败,导致如下错误:

    top: failed tty set: 被中断的系统调用
    

    这通常是因为:

    • 终端没有正确打开;
    • top 被挂起时已经失去了终端的控制权;
    • 或者你的终端模拟器/环境不支持这种操作。

    ✅ 解决方案

    以下是解决这个问题的几种方法:

    1. 避免将交互式程序放入后台

    • 如果你只是想查看 top 的输出,可以考虑:
      • 使用 top -b(批处理模式):
        top -b > output.txt
        
      • 或者使用 tmux / screen 等终端多路复用器来管理交互式程序。

    2. 使用 disown 避免作业被挂起

    • 如果你确实想将 top 放入后台运行,可以这样做:
      top &
      disown %1
      
      • disown %1 会将该作业从 shell 的作业表中移除,使其不再受 shell 控制。
      • 这样 top 就不会被自动挂起。

    3. 使用 nohup& + disown 结合

    • 如果你希望 top 在后台运行且不受终端关闭影响:
      nohup top &
      

    4. 直接在前台运行 top

    • 如果你只需要查看 top 的实时数据,可以直接在前台运行:
      top
      

    🧠 总结

    | 项目 | top | sleep | |------|-------|---------| | 是否交互式 | ✅ 是 | ❌ 否 | | 是否可后台运行 | ❌ 会被挂起 | ✅ 可后台运行 | | fg 是否可用 | ❌ 报错 | ✅ 正常工作 |


    💡 补充说明

    如果你真的需要将 top 放入后台运行,推荐使用 -b 参数:

    top -b > top_output.txt
    

    这样 top 就不会尝试与终端交互,从而避免被挂起。


    📝 修改后的代码示例(推荐)

    如果你想让 top 在后台运行而不被挂起,可以这样写:

    top -b > top_output.txt &
    disown %1
    

    或者更简单的方式:

    nohup top -b > top_output.txt &
    

    如果你还有其他关于作业控制、bgfgjobs 的疑问,欢迎继续提问!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 8月31日
  • 已采纳回答 8月23日
  • 创建了问题 8月23日