“bash:此shell中没有作业控制”是什么意思?

bwleehnv  于 2022-11-02  发布在  Linux
关注(0)|答案(5)|浏览(214)

我认为这与父进程创建新的子进程有关,并且没有tty。有人能解释一下引擎盖下面的细节吗?即,bash的相关工作模型,进程创建等?
这可能是一个非常广泛的主题,所以也非常感谢帖子的指针。我在谷歌上搜索了一段时间,所有的结果都是关于非常具体的案例,没有一个是关于幕后的故事。为了提供更多的背景,下面是导致“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

这一行:
bash -i -c "ssh -D 7070 -N user@my-ssh.example.com > /dev/null"
是“bash:此shell中没有作业控制”来源。

zi8p0yeb

zi8p0yeb1#

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


# ! /bin/bash

set -m
rfbsl7qr

rfbsl7qr2#

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

作业是一个命令或管道。如果你运行ls,那就是一个作业。如果你运行ls|more,那仍然只是一个作业。如果你运行的命令启动了它自己的子进程,那么它们也属于同一个作业,除非它们被故意分离。
如果没有作业控制,您可以通过在命令行中添加&来将作业置于后台,这就是您所拥有的全部控制。
使用作业控制,您还可以:
1.使用CtrlZ暂停正在运行的前台作业
1.使用fg在前台恢复挂起的作业
1.使用bg在后台恢复挂起的作业
1.使用fg将正在运行的后台作业置于前台
shell维护一个作业列表,您可以通过运行jobs命令来查看该列表。(不同于组成作业的进程的PID)。您可以使用作业号,前缀为%,作为fgbg的参数,以选择前台或后台的作业。%jobnumber表示法也可用于shell的内置kill命令。这可能很方便,因为作业编号从1开始分配,因此它们比PID短。
还有用于最近前景化作业的快捷方式%+和用于先前前景化作业的快捷方式%-,因此您可以使用CtrlZ后跟fg %-在两个作业之间快速来回切换(暂停当前一、恢复另一个),而不必记住数字。或者你可以使用命令本身的开头。如果您暂停了ffmpeg命令,恢复它就像fg %ff一样简单(假设没有其他活动作业以“ff”开头)。作为最后一个快捷方式,您不必键入fg。只需输入%-作为命令即可将前一个作业置于前台。
“但是我们为什么需要这个呢?”我可以听到你在问。“如果我想运行另一个命令,我可以启动另一个shell。”没错,多任务处理有很多种方式。在正常的一天,我会在tty 1到tty 10上运行登录shell(是的,有6个以上,你只需要激活它们),其中一个将运行一个屏幕会话,其中有4个屏幕,另一个可能有一个ssh运行在它上面,其中有另一个屏幕会话运行在远程机器上,加上我的X会话与3或4个xterms。
如果我正在运行vilessaptitude或其他交互式程序,我需要运行几个其他快速命令来决定如何继续,CtrlZ,运行命令,fg是自然而快速的。(在很多情况下,交互式程序都有一个!键绑定来为您运行外部命令;我不认为这是好的,因为你没有得到你的shell的历史,命令行编辑器,和完成系统的好处。)我发现每当我看到有人启动一个次要的xterm/screen/whatever运行一个命令,看它两秒钟,然后退出时,我很难过。
现在谈谈你的剧本。总的来说,它似乎写得不太好。有问题的那一行:

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

我不明白为什么ssh命令被传递到一个单独的shell而不是直接从主脚本执行,更不用说为什么有人向其中添加了-i-i选项告诉shell以交互方式运行,激活作业控制无论单独的shell和-i背后的目的是什么,关于作业控制的警告是一个副作用。我猜这是一个绕过ssh的一些不受欢迎的特性的黑客。当你这样做的时候,你应该注解它。

yqhsw0fo

yqhsw0fo3#

其中一个可能的选项是无法访问tty。
引擎盖下:

  1. bash检查会话是否是交互式的,如果不是-则不进行作业控制。
    1.如果设置了forced_interactive,则跳过检查stderr是否连接到tty,bash再次检查in是否可以打开/dev/tty进行读写访问。
    1.则检查是否使用了新的线路规程,如果没有使用,则也禁用作业控制。
    1.当(且仅当)我们只是将进程组设置为我们的pid,从而成为进程组领导者,并且终端与我们(新)的进程组不在同一个进程组中,则将终端的进程组设置为我们(新)的进程组。如果失败,则将我们的进程组设置回原来的状态(这样我们仍然可以从终端读取数据),并关闭作业控制。
    1.如果上述所有操作均失败,您将看到以下消息。
    我部分引用了bash源代码中的注解。
    根据问题作者的额外要求:
    http://tiswww.case.edu/php/chet/bash/bashtop.html在这里您可以找到bash本身。
    如果你能阅读C代码,得到源代码,在里面你会发现job.c-这将解释你更多的“引擎盖下”的东西。
cbjzeqam

cbjzeqam4#

我在自己的嵌入式系统上遇到了一个问题,我通过运行带有“setsid”的getty进程摆脱了“无作业控制”错误,根据其手册页,该进程使用新的会话ID启动了一个进程。

g0czyy6m

g0czyy6m5#

遇到这个问题仅仅是因为我把一个先前执行的命令和%前缀一起错误地复制到了zsh中,像% echo this而不是echo this

相关问题