首页 > 解决方案 > Shell:分叉(守护)一个子shell,使其在其 tmux 会话结束后仍然存在

问题描述

我正在尝试分叉一个子shell,该子shell 在创建它的 tmux 会话终止后仍然存在。我尝试了双叉策略:

insubshell-eval () {
    local cmd="$@"
    (
        eval "$cmd"
    )
}
gquote () {
    # quotes the arguments
    print -r -- "${(q+@)@}"
}
awaysh1 () {
    local cmd="$(gquote "$@") & ; disown "
    setopt LOCAL_OPTIONS NO_NOTIFY NO_MONITOR
    insubshell-eval "$cmd" &
     &> /dev/null < /dev/null || return $?
    disown &> /dev/null || true
}
awaysh-exit () {
    awaysh1 "$@"
    exit 0
}
awaysh-doublefork () {
    awaysh1 awaysh-exit "$@"
}

然后我使用上面的方法播放一些音频来检查进程何时终止:

tmux kill-ses -t t1 ; tmux new-session -d -s t1 zsh -c "awaysh-doublefork play '/x/y.ogg'"

这个命令有竞争条件(我不知道为什么),有时会正确播放文件,但更多时候什么都不播放。

我唯一想到的是双分叉进程仍然与原始进程共享它的进程组 ID,因此被 tmux 发出了被遗忘的信号。但是如何更改此进程 ID?

PS:我不能用nohup。我希望解决方案是纯的zsh

标签: shellforkzshdaemontmux

解决方案


用于nohup让进程在生成它的 shell 死亡后继续运行。它必须是一个进程,而不是一个子shell。

$ man nohup

如何使用的快速示例:

$ nohup program argument &

推荐阅读