Bash kill进程未完成

Bash kill进程未完成,bash,background-process,kill,bash-completion,Bash,Background Process,Kill,Bash Completion,我有一个bash主题,它以惰性的方式显示提示符的各个部分。因此,它在开始时显示一组信息,然后延迟加载信息,从后台进程加载和重写提示需要时间 现在,由于延迟加载的呈现是异步的,如果您在异步部分未呈现的情况下从当前工作目录移动到另一个工作目录,我们将在错误的位置获得错误的信息。例如: 异步呈现函数由以下函数调用: # Check the async side of the prompt if available set +m _render_async & 现在为了防止这种情

我有一个bash主题,它以惰性的方式显示提示符的各个部分。因此,它在开始时显示一组信息,然后延迟加载信息,从后台进程加载和重写提示需要时间

现在,由于延迟加载的呈现是异步的,如果您在异步部分未呈现的情况下从当前工作目录移动到另一个工作目录,我们将在错误的位置获得错误的信息。例如:

异步呈现函数由以下函数调用:

  # Check the async side of the prompt if available
  set +m
  _render_async &
现在为了防止这种情况发生,我添加了一个检查,以便在呈现提示符之前查看是否有任何后台进程正在等待呈现不在当前目录中的异步端并将其杀死

# Check and kill any irreelvant background jobs
# Outdated background jobs are any gaudi::async_render executed on folders
# other than the current working directory $PWD  

export PROMPT_COMMAND="gaudi::kill_outdated_asyncRender; $PROMPT_COMMAND"

# Kill all background gaudi::render_async that are running in the wrong context
# Wrong context is any directory (CWD) that is not the current directory
# USAGE:
#   gaudi::kill_outdated_asyncRender

gaudi::kill_outdated_asyncRender() {
  joblist="$(jobs | grep '_render_async.*wd:' | cut -d "[" -f2 | cut -d "]" -f1 | tr '\n' ' ')"
  IFS=' '
  for job in $joblist; do kill "%$job"; done
}
这一点现在非常有效,我看不到错误的渲染,但我注意到,现在函数上的bash完成混乱,项目没有按预期显示,如下所示:


正如你所看到的那样,完成元素不在同一行,只是被打断了。删除
kill\u outlated\u asyncRender
可以修复此行为,但我仍然不确定为什么会发生这种情况。

gaudi::kill\u outlated\u asyncRender
设置
IFS
,但不会重置它。这具有全球意义,因为它在整个bash中用于:

IFS变量在shell(Bourne、POSIX、ksh、bash)中用作输入字段分隔符(或内部字段分隔符)。本质上,它是一个特殊字符字符串,在拆分输入行时,这些字符将被视为单词/字段之间的分隔符

修改
IFS
是一种常见模式,但您需要重置它:

gaudi::kill_outdated_asyncRender() {
  joblist="$(jobs | grep '_render_async.*wd:' | cut -d "[" -f2 | cut -d "]" -f1 | tr '\n' ' ')"
  local oIFS=$IFS
  IFS=' '
  for job in $joblist; do kill "%$job"; done
  IFS=$oIFS
}
一般来说,请保持
$PROMPT\u命令的简单性。显然存在延迟问题,但它本身也很难调试。根据这些思路,我会提出一些有针对性的建议,以减少副作用的可能性:

  • 在后台生成进程时,将其PID记录到一个文件中。然后,在kill函数中使用此文件的内容,而不是
    jobs | grep
    管道

  • 不要在目录更改时计算这些值,而是在登录期间和定期(通过cron)预计算它们(在后台)。您还有一个同步更新值的“刷新”命令,这样,如果您对所看到的内容有疑问,就可以始终获得最新的值


  • 您正在进行一些严重的黑客攻击,以实现一件至少值得怀疑的事情。如果我看得对,您可以异步执行提示输出,因为收集信息需要很长时间,因此让用户等待会很麻烦。这也意味着,在每个命令之后,您都会让计算机执行一项乏味的任务。这是不鼓励的,因为它会在没有需要的情况下延迟主机。如果用户确实需要花费很长时间的信息,可以让用户键入一个小命令。否则,我建议不要在提示符中显示信息,而是在其他地方(一个单独的窗口左右)显示信息。我注意到,您可以在
    gaudi::kill_oplated_asyncRender
    中更改
    IFS
    。我建议保存当前IFS值并在函数末尾将其重置,或者仅将其绑定到
    for
    循环行。其他一些一般性意见:(1)我建议您将后台进程的PID保存到一个文件中,并使用该文件的内容而不是
    作业| grep
    管道。(2) 你能预先计算这些值吗?例如,在
    .bash\u profile
    期间生成后台作业,以遍历目标目录并将值缓存到文件中。然后,您也可以让cron执行同样的操作。然后,提示命令只需读取文件即可。感谢@bishop提供的提示。。我现在将尝试执行其中一些ideas@bishop您恢复
    IFS
    的想法是一个很好的提示。事实上,我以一种不同的方式来循环浏览工作列表,这似乎起到了作用。我很乐意接受你的回答:)