什么"bash:这个shell中没有工作控制"是什么意思?

lua*_*nyi 47 linux bash

我认为这与创建新子进程的父进程有关,并且没有tty.谁能解释引擎盖下的细节?即bash,流程创建等相关工作模型?

这可能是一个非常广泛的主题,因此对帖子的指示也非常感激.我用谷歌搜索了一段时间,所有结果都是关于非常具体的情况,没有一个是关于场景背后的故事.为了提供更多上下文,下面是shell脚本,导致'bash:此shell中没有作业控件'.

#! /bin/bash

while [ 1 ]; do
    st=$(netstat -an |grep 7070 |grep LISTEN -o | uniq)
    if [ -z $st ]; then
        echo "need to start proxy @$(date)"
        bash -i -c "ssh -D 7070 -N user@my-ssh.example.com > /dev/null"
    else
        echo "proxy OK @$(date)"
    fi
    sleep 3
done
Run Code Online (Sandbox Code Playgroud)

这一行:

bash -i -c "ssh -D 7070 -N user@my-ssh.example.com > /dev/null"

是"bash:这个shell中没有工作控制"来自哪里.

小智 39

您可能需要启用作业控制:

#! /bin/bash   
set -m
Run Code Online (Sandbox Code Playgroud)

  • _WHAAAAAAAT?_ 为什么这不是默认值? (6认同)
  • 在 Docker 容器中运行良好!为容器的入口点执行后台工作,然后将其恢复。向不支持从文件播种的数据库提供数据... (6认同)
  • 谢谢,但请解释一下“作业控制”的含义,以回答““bash:此 shell 中没有作业控制”是什么意思?” (2认同)

Ala*_*rry 34

作业控制是shell和tty驱动程序中的一组功能,允许用户从单个交互式shell管理多个作业.

作业是单个命令或管道.如果你跑ls,那就是工作.如果你跑ls|more,那仍然只是一份工作.如果您运行的命令启动了自己的子进程,那么它们也将属于同一作业,除非它们被故意分离.

如果没有作业控制,您可以通过添加&到命令行将作业放在后台.这就是你拥有的所有控制权.

通过作业控制,您还可以:

  1. 暂停正在运行的前台作业 CtrlZ
  2. 使用后台恢复暂停的作业 fg
  3. 使用后台恢复暂停作业 bg
  4. 将正在运行的后台作业带到前台 fg

shell通过运行jobs命令维护一个可以看到的作业列表.为每个工作编号分配一个工作编号(不同于组成工作的工艺的PID).您可以使用%作为参数的作业编号作为参数fgbg选择作业到前景或背景.%jobnumber表示法也可以被shell的内置kill命令接受.这很方便,因为作业编号从1开始分配,所以它们比PID短.

%+最近的前提工作和%-先前的工作也有快捷方式,因此您可以在两个工作之间快速切换,CtrlZ然后fg %-暂停(暂停当前工作,恢复另一个工作),而不必记住数字.或者您可以使用命令本身的开头.如果您已暂停ffmpeg命令,则恢复它就像fg %ff(假设没有其他活动作业以"ff"开头)一样容易.作为最后一个捷径,你不必输入fg.只需输入%-命令即可显示上一个作业.

"但为什么我们需要这个呢?" 我能听到你问."如果我想运行另一个命令,我可以启动另一个shell." 没错,有多种多任务处理方式.在正常的一天,我有登录shell在tty1到tty10上运行(是的,有超过6个,你只需要激活它们),其中一个将运行一个屏幕会话,其中有4个屏幕,另一个可能正在运行ssh在它上面,在远程机器上运行另一个屏幕会话,加上我的X会话有3或4个xterms.我仍然使用工作控制.

如果我在中间vilessaptitude或任何其他互动的事情,我需要运行其他几个快捷命令来决定如何进行,CtrlZ运行的命令,fg是自然和快速.(在很多情况下,一个交互式程序有一个!键绑定来为你运行一个外部命令;我认为这并不好,因为你没有得到你的shell历史,命令行编辑器和完成系统的好处.)我每当我看到有人发起一个辅助xterm /屏幕/无论运行一个命令,查看它两秒钟,然后退出时,都会感到难过.

现在关于你的这个剧本.一般来说,它似乎没有完整的书面形式.有问题的一行:

bash -i -c "ssh -D 7070 -N user@my-ssh.example.com > /dev/null"
Run Code Online (Sandbox Code Playgroud)

令人困惑.我无法弄清楚为什么ssh命令被传递到一个单独的shell而不是直接从主脚本执行,更不用说为什么有人添加-i它了.该-i选项告诉shell以交互方式运行,这会激活作业控制(以及其他内容).但它实际上并没有以交互方式使用.无论单独的外壳背后的目的是什么-i,关于工作控制的警告都是副作用.我猜这是一个克服ssh的一些不良特性的黑客攻击.这就是当你这样做时,你应该评论它.


fav*_*tti 20

其中一个可能的选择是无法访问tty.

引擎盖下:

  1. bash检查会话是否是交互式的,如果不是 - 没有工作控制.
  2. 如果设置了forced_interactive,则检查stderr是否附加到tty被跳过并再次进行bash检查,是否可以打开/dev/tty以进行读写访问.
  3. 然后它检查是否使用了新的线路规则,如果没有,则也禁用工作控制.
  4. 如果(且仅当)我们将我们的流程组设置为我们的pid,从而成为流程组负责人,并且终端与我们的(新)流程组不在同一流程组中,则将终端的流程组设置为我们(新的)过程组.如果失败,请将我们的进程组设置回原来的状态(这样我们仍然可以从终端读取)并关闭作业控制.
  5. 如果以上所有内容都失败了,您会看到该消息.

我部分引用了bash源代码的注释.

[编辑]

根据问题作者的额外要求:

http://tiswww.case.edu/php/chet/bash/bashtop.html在这里你可以找到bash本身.

如果你可以阅读C代码,获取源代码tarball,你会发现job.c- 你会发现更多"引擎盖下"的内容.:)