Intereting Posts

Выполнять команду в текущей оболочке перед каждой подсказкой

Я бы хотел, чтобы текущий статус 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 за его ответ, который помог мне понять актуальную проблему!