在构建 bash 提示符时终止后台进程
Killing a background process while building a bash prompt
我已经设法让我的 bash 提示延迟加载一些组件以获得异步渲染的感觉。延迟加载功能作为后台进程运行 (render_async &)
.
从下面的截屏视频中,您可以看到提示实际上是如何立即加载一部分和另一部分的 "lazy loads"。但是,我注意到,如果您在加载异步部分之前更改目录,新提示将被错误的上下文覆盖。
我解决这个问题的思路如下:
- 使用
jobs
命令检查后台进程
- 我发现作业命令在不在当前工作目录后台的进程旁边显示
wd:*
- 找到所有并杀死所有具有该模式的后台进程以避免这种覆盖
我在我的异步命令中添加了一个睡眠来模拟它,我可以看到后台进程挂起。
[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> &"
replaces
the current shell, no new process is created, that's why I'm starting
a new shell to call exec.
Then you can kill the process with:
pkill -f MyUniqueProcessName You can start more than one process under
the same name, then pkill -f will kill all of them.
但这一直告诉我我试图传递给 <command>
的异步函数没有找到,我怀疑它与它是一个自定义函数的事实有关,那就是分叉一个新的 bash 进程,但我不是这里的专家。
谢谢
管道创建一个隐式子shell,因此在 kill
是 运行 的管道到 while
循环中,来自父项的作业是不可见的。怎么样,这至少会杀死第一份工作?
job="$(jobs | grep 'render_async.*wd:' | cut -d "[" -f2 | cut -d "]" -f1)"
kill "%$job"
在我的测试中,$(...)
发生在当前 shell 中,至少最初是这样,因此作业 table 是可见的。示例:
$ cat &
[1] 8296
$ jobs
[1]+ Stopped cat
$ echo "$(jobs| cut -d "[" -f2 | cut -d "]" -f1|head -1)"
1
(顺便说一句,你想干掉的工作总是有相同的工作编号吗?你能不能硬编码 %2
,或者随便什么?)
编辑 多作业:
joblist="$(jobs| sed -E 's/^[^0-9]*([0-9]+).*$//'|tr '\n' '@')"
# E.g., 1@2@
IFS='@' # Split on @
for job in $joblist # No double-quotes!
do
kill "%$job"
done
来自 shell 提示的工作示例:
$ cat&
[1] 8824
$ cat&
[2] 6452
[1]+ Stopped cat
$ jobs
[1]- Stopped cat
[2]+ Stopped cat
$ joblist="$(jobs| sed -E 's/^[^0-9]*([0-9]+).*$//'|tr '\n' '@')"
$ IFS=@
$ for job in $joblist; do kill "%$job" ; done
[1]- Stopped cat
[2]+ Stopped cat
$ jobs
[1]- Terminated cat
[2]+ Terminated cat
$ jobs
$
我选择 @
作为分隔符,因为我认为它对 shell 没有任何特殊意义。
我不知道它在 PS1-函数环境中是否有所不同。
我已经设法让我的 bash 提示延迟加载一些组件以获得异步渲染的感觉。延迟加载功能作为后台进程运行 (render_async &)
.
从下面的截屏视频中,您可以看到提示实际上是如何立即加载一部分和另一部分的 "lazy loads"。但是,我注意到,如果您在加载异步部分之前更改目录,新提示将被错误的上下文覆盖。
我解决这个问题的思路如下:
- 使用
jobs
命令检查后台进程 - 我发现作业命令在不在当前工作目录后台的进程旁边显示
wd:*
- 找到所有并杀死所有具有该模式的后台进程以避免这种覆盖
我在我的异步命令中添加了一个睡眠来模拟它,我可以看到后台进程挂起。
[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> &"
replaces the current shell, no new process is created, that's why I'm starting a new shell to call exec.Then you can kill the process with:
pkill -f MyUniqueProcessName You can start more than one process under the same name, then pkill -f will kill all of them.
但这一直告诉我我试图传递给 <command>
的异步函数没有找到,我怀疑它与它是一个自定义函数的事实有关,那就是分叉一个新的 bash 进程,但我不是这里的专家。
谢谢
管道创建一个隐式子shell,因此在 kill
是 运行 的管道到 while
循环中,来自父项的作业是不可见的。怎么样,这至少会杀死第一份工作?
job="$(jobs | grep 'render_async.*wd:' | cut -d "[" -f2 | cut -d "]" -f1)"
kill "%$job"
在我的测试中,$(...)
发生在当前 shell 中,至少最初是这样,因此作业 table 是可见的。示例:
$ cat &
[1] 8296
$ jobs
[1]+ Stopped cat
$ echo "$(jobs| cut -d "[" -f2 | cut -d "]" -f1|head -1)"
1
(顺便说一句,你想干掉的工作总是有相同的工作编号吗?你能不能硬编码 %2
,或者随便什么?)
编辑 多作业:
joblist="$(jobs| sed -E 's/^[^0-9]*([0-9]+).*$//'|tr '\n' '@')"
# E.g., 1@2@
IFS='@' # Split on @
for job in $joblist # No double-quotes!
do
kill "%$job"
done
来自 shell 提示的工作示例:
$ cat&
[1] 8824
$ cat&
[2] 6452
[1]+ Stopped cat
$ jobs
[1]- Stopped cat
[2]+ Stopped cat
$ joblist="$(jobs| sed -E 's/^[^0-9]*([0-9]+).*$//'|tr '\n' '@')"
$ IFS=@
$ for job in $joblist; do kill "%$job" ; done
[1]- Stopped cat
[2]+ Stopped cat
$ jobs
[1]- Terminated cat
[2]+ Terminated cat
$ jobs
$
我选择 @
作为分隔符,因为我认为它对 shell 没有任何特殊意义。
我不知道它在 PS1-函数环境中是否有所不同。