仅当大于 0 时才显示作业计数

仅当大于 0 时才显示作业计数

我有一个jobscount()功能:

jobscount() {
   local stopped='$(jobs -s | wc -l | tr -d " ")'
   local running='$(jobs -r | wc -l | tr -d " ")'
   echo -n "${running}r/${stopped}s"
}

我在我的中使用这个函数$PS1

PS1=" \w $(jobscount) \$ "

唯一的问题是,如果没有后台进程运行或没有停止的作业,则该函数无用地占用$PS1空间。我想要的是如果 或stoppedrunning大于0,只有那时它出现了。

答案1

你们把这种方式搞得太复杂了。只需检查输出是否jobs非空,然后添加\j到您的 PS1 字符串。

if [ -n "$(jobs -p)" ]; then echo "\j"; fi

这是我的提示中的一个片段:

#Show number of jobs if at least one job
export PS1+='`if [ -n "$(jobs -p)" ]; then echo "(\j)"; fi`'

答案2

首先,我建议修正你的引用。从命令提示符独立运行时,当前函数不会输出有用的数据。

然后添加一个条件,使用OR 列表分隔符, 之前echo

jobscount() {
  local stopped=$(jobs -sp | wc -l)
  local running=$(jobs -rp | wc -l)
  ((running+stopped)) && echo -n "${running}r/${stopped}s "
}

PS1=' \w $(jobscount)\$ '

我还建议添加-pjobs调用中,以便它们仅输出进程 PID。否则,yes $'foo\nbar' &在 2 行上列出的命令将被计数两次。

答案3

由于您在每次提示时都运行此命令,因此值得节省一些外部调用。

要仅在有后台作业时显示计数,请检查数字,如果它们全为 0,则不要打印任何内容。

运行jobs -p仅获取进程 ID,更容易可靠地解析。

jobscount() {
  set -- $(jobs -rp)
  set $# $(jobs -sp)
  set $1 $(($#-1))
  if [ $1 -ne 0 ] || [ $2 -ne 0 ]; then echo "${1}r/${2}s"; fi
}
PS1=' \w $(jobscount) \$ '

顺便说一句,在分配给 时请注意右侧的引号PS1。使用双引号,当您设置变量时会调用该函数。您需要使用单引号,以便 的值PS1包含文本$(jobscount),并且每次显示提示时都会调用该函数。

您可以通过PROMPT_COMMAND设置变量而不是使用函数的输出来保存一个分叉。

set_jobscount () {
  set $(jobs -rp)
  set $# $(jobs -sp)
  set $1 $(($#-1))
  if [ $1 -ne 0 ] || [ $2 -ne 0 ]; then
    jobscount="${1}r/${2}s"
  else
    jobscount=
  fi
}
PROMPT_COMMAND="$PROMPT_COMMAND
set_jobscount"
PS1=' \w ${jobscount} \$ '

和往常一样,zsh 更简单(虽然看起来很神秘)。

precmd () {
  jobscount=${(M)#${jobstates%%:*}:#running}r/${(M)#${jobstates%%:*}:#suspended}s
  if [[ $jobscount == r0/s0 ]]; then jobscount=; fi
}
setopt prompt_subst
PS1='… ${jobscount} …'

这里jobstatesZsh 提供的变量来自zsh/parameter模块。#running并将#suspended输出分开以仅包括正在运行或挂起的作业。(M)标志并%%来自参数扩展(M)flag 删除不匹配的元素并%%删除:输出中之后的任何内容$jobstates

答案4

PS1 中的 $() 怎么样,例如:

export PS1='\w $(if test "\j" -ne "0"; then echo -e "\033[32m\j "; fi )\[\033[01;35m\]\$\[\033[00m\] '

相关内容