在每次提示之前在当前 shell 中执行命令

在每次提示之前在当前 shell 中执行命令

我希望jobs在我的终端标题中显示当前状态。在 Bash 中,我可以使用PROMPT_COMMAND它。 Korn Shell (ksh93) 没有这个功能。

其他答案建议在内部使用命令替换$PS1,这在一般情况下工作正常,但不适用于命令jobs。这里的问题是人们jobs对工作的担忧当前外壳,但命令替换(即PS1='...$(jobs)...')是在子外壳,所以没有工作机会。

我知道的唯一机制是trap '... jobs ...' DEBUG,但这会执行得太频繁。您是否知道如何在当前 shell 的上下文中在每个提示符下运行一次命令,或者这在 Korn shell 中不可能吗?!

答案1

默认情况下,如果您刚刚设置,PS1="...."那么引号内的内容将在您设置时进行评估。

但是,如果您将其包含在内部',则会在显示时对其进行评估。并且它不会导致$(jobs).

例如

$ PS1='
> $(jobs)
> $ '


$ sleep 1000 &
[1] 7541

[1] +  Running                 sleep 1000 &
$ sleep 1000 &
[2] 7543

[2] +  Running                 sleep 1000 &
[1] -  Running                 sleep 1000 &
$ kill %1
[1] - Terminated               sleep 1000 &

[2] +  Running                 sleep 1000 &
$ kill %2
[2] + Terminated               sleep 1000 &


$ 

(此测试在 Debian Jessie 上使用 ksh93 完成,但应该适用于所有 ksh93 变体;我没有任何 ksh88 可供测试。)

答案2

我的实际问题是(与我的问题中的简化示例相反),我实际上调整了jobs函数中的输出,将运行与停止的作业分开。

这是我的 Bash 代码:

typeset runningJobs=$(jobs -r | wc -l)
typeset stoppedJobs=$(jobs -s | wc -l)

我以这种方式将其移植到 Korn shell:

typeset runningJobs=$(jobs | grep -c ' Running ')
typeset stoppedJobs=$(jobs | grep -c ' Stopped ')

管道命令替换内部$(...)实际上导致jobs在子 shell 中执行(因此总是不产生任何输出)。通过捕获变量中的输出,可以防止这种情况。以下重写按预期工作:

typeset jobOutput=$(jobs)
typeset runningJobs=$(printf '%s\n' "$jobOutput" | grep -c ' Running ')
typeset stoppedJobs=$(printf '%s\n' "$jobOutput" | grep -c ' Stopped ')

感谢@StephenHarris 的回答,这帮助我理解了实际​​问题!

相关内容