Я бы хотел, чтобы текущий статус jobs
отображался в заголовке моего терминала. В Bash я могу использовать для этого PROMPT_COMMAND
. У Korn Shell (ksh93) этого нет.
Другие ответы предполагают использование подстановки команд внутри $PS1
, которая отлично работает в общем случае, но не для команды jobs
. Проблема здесь в том, что jobs
связаны с заданиями текущей оболочки , но подстановка в командной PS1='...$(jobs)...'
выполняется (например, PS1='...$(jobs)...'
), поэтому нет заданий.
Единственный механизм, о котором я знаю, – это trap '... jobs ...' DEBUG
, но это слишком часто выполнялось. Вы знаете способ запуска команд в контексте текущей оболочки, один раз в каждом приглашении, или это невозможно в оболочке Korn ?!
По умолчанию, если вы просто установите 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 для тестирования.)
Моя фактическая проблема заключалась в том, что (в отличие от упрощенного примера в моем вопросе), я фактически массировал выходные jobs
в функции, отделяя работу от остановленных заданий.
Это мой код для Bash:
typeset runningJobs=$(jobs -r | wc -l) typeset stoppedJobs=$(jobs -s | wc -l)
который я поместил в оболочку Korn таким образом:
typeset runningJobs=$(jobs | grep -c ' Running ') typeset stoppedJobs=$(jobs | grep -c ' Stopped ')
Конвейер внутри подстановки $(...)
самом деле вызывал выполнение jobs
в подоболочке (и поэтому всегда не давал выхода). Удерживая вывод в переменной, это можно предотвратить. Следующий переписывающий файл работает так, как ожидалось:
typeset jobOutput=$(jobs) typeset runningJobs=$(printf '%s\n' "$jobOutput" | grep -c ' Running ') typeset stoppedJobs=$(printf '%s\n' "$jobOutput" | grep -c ' Stopped ')
Благодаря @StephenHarris за его ответ, который помог мне понять актуальную проблему!