【发布时间】:2018-09-21 04:10:57
【问题描述】:
我已经设法让我的 bash 提示延迟加载一些组件以产生异步渲染的感觉。延迟加载功能作为后台进程运行,(render_async &)。
从下面的截屏视频中,您可以看到提示实际上是如何立即加载部分内容以及其他“延迟加载”的。但是,我注意到,如果您在加载异步部分之前更改目录,则新提示将被错误的上下文覆盖。
我解决这个问题的思路如下:
- 使用
jobs命令检查后台进程 - 我发现jobs 命令在不在当前工作目录后台的进程旁边显示
wd:* - 查找并终止所有具有该模式的后台进程以避免这种覆盖
我在异步命令中添加了一个 sleep 来模拟它,我可以看到后台进程挂起。
[1] Running render_async &
[2]- Running render_async & (wd: ~/Projects/My Personal Space/blog-core)
[3]+ Running render_async &
我继续写道:
jobs | grep 'render_async.*wd:' | cut -d "[" -f2 | cut -d "]" -f1 | while read -r line ; do
kill "%$line"
done
理论上应该解析其他目录中后台作业的id并杀死它们。但是在实践中,我不断得到上面的例子kill: %2: no such job。
当我在 shell 本身中执行相同的 kill 命令时,它可以完美运行。
在此不胜感激。
其他想法
我尝试命名我的分叉进程(通过将 CWD 附加到函数名称来命名每个异步进程),灵感来自 https://askubuntu.com/questions/153900/how-can-i-start-a-process-with-a-different-name,其中:
bash -c "exec -a MyUniqueProcessName <command> &"替换 当前的shell,没有创建新进程,这就是我开始的原因 调用 exec 的新 shell。然后你可以终止进程:
pkill -f MyUniqueProcessName 下可以启动多个进程 相同的名字,然后 pkill -f 将杀死所有的人。
但这一直告诉我,我试图传递给 <command> 的异步函数没有找到,我怀疑它与它是一个自定义函数这一事实有关,并且是一个新的 bash过程,但我不是这里的专家。
谢谢
【问题讨论】:
-
您使用的终端是否提供标题窗口或其他可以写入状态的带外位置? 改进这种方法肯定是可能的,但我不确定你是否能够使其完全健壮:如果一个新进程认为它拥有终端,但你的旧 shell 的子进程还在打印,冲突在所难免。
-
感谢@CharlesDuffy 的评论。我正在使用 MacOSX 终端,但很想看看我如何改进它并使其变得强大
-
while是一个隐含的子shell,据我所知,因此kill在此期间可能无法看到作业。 -
@cxw,不,
while不会创建子外壳;在到while的管道中,负责的是管道,而不是while。 (不过,你是对的,它不会是同一个 shell 实例并且不会有相同的作业表;对于非交互式脚本,可以使用lastpipe来更改该行为,但它不适用于作业控制)。 -
...一般来说,当你从 bash 启动某些东西并想稍后杀死它时,你应该保留 pid:
foo & foo_pid=$!让你稍后kill "$foo_pid"(并检查它是否仍在运行if kill -0 "$foo_pid" &>/dev/null; then等)。
标签: bash shell command-prompt background-process kill