我希望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 的回答,这帮助我理解了实际问题!