相关疑难解决方法(0)

在哪些情况下,当您注销时,SIGHUP 不会发送到作业?

我读了一个声称正在运行的用户的答案

foo 2>&1 >& output.log &
Run Code Online (Sandbox Code Playgroud)

foo即使他们注销,也会导致继续运行。据该用户称,这甚至可以通过 SSH 连接工作。

我并不真正相信这一点,因为我的印象是,在与 SSH 断开连接或终止 TTY 的情况下,shell 及其进程会收到 SIGHUP,导致它们终止。这一点,我的假设下,被使用的唯一理由nohup在这样的情况下,或者tmuxscreen等。

然后我查看了glibc 的手册

该信号还用于向与该会话相关联的作业报告终端上控制进程的终止;此终止有效地断开会话中的所有进程与控制终端的连接。

这似乎证实了我的想法。但进一步看,它说

如果进程是具有控制终端的会话领导者,则向前台作业中的每个进程发送 SIGHUP 信号,并且控制终端与该会话解除关联。

那么,这是否意味着置于后台的作业将不会收到 SIGHUP?

令我更加困惑的是,我运行了一个交互式 Zsh 会话,运行yes >& /dev/null &并输入了exit,当 Zsh 警告我有正在运行的作业时,exit第二次输入后,它告诉我它已经 SIGHUPed 一个作业。在 Bash 中执行完全相同的操作会使工作继续运行……

ssh signals tty

13
推荐指数
1
解决办法
9396
查看次数

使用前台终端访问在后台运行命令

我正在尝试创建一个可以运行任意命令的函数,与子进程交互(省略细节),然后等待它退出。如果成功,打字run <command>看起来就像一个裸的<command>.

如果我不与子进程交互,我会简单地写:

run() {
    "$@"
}
Run Code Online (Sandbox Code Playgroud)

但是因为我需要在它运行时与之交互,所以我使用coproc和 进行了更复杂的设置wait

run() {
    exec {in}<&0 {out}>&1 {err}>&2
    { coproc "$@" 0<&$in 1>&$out 2>&$err; } 2>/dev/null
    exec {in}<&- {out}>&- {err}>&-

    # while child running:
    #     status/signal/exchange data with child process

    wait
}
Run Code Online (Sandbox Code Playgroud)

(这是一个简化。虽然coproc重定向和所有重定向在这里并没有真正做任何不能做的有用的"$@" &事情,但我在我的实际程序中需要它们。)

"$@"命令可以是任何东西。我拥有的功能可以使用run ls等等run make,但是当我这样做时它失败了run vim。我认为它失败了,因为 Vim 检测到它是一个后台进程并且没有终端访问权限,所以它不会弹出一个编辑窗口,而是自己挂起。我想修复它,以便 Vim 正常运行。

如何coproc "$@"在“前台”中运行而父 shell 成为“后台”?“与孩子交互”部分既不读取也不写入终端,所以我不需要它在前台运行。我很高兴将 tty 的控制权交给协进程。

对于我正在做的事情来说,重要的run() …

shell job-control tty background-process coprocesses

7
推荐指数
2
解决办法
3444
查看次数