Уничтожение фонового процесса при создании приглашения bash - PullRequest
0 голосов
/ 20 сентября 2018

Мне удалось заставить мой bash-запрос лениво загружать некоторые компоненты, чтобы создать ощущение асинхронного рендеринга.Функция отложенной загрузки запускается как фоновый процесс с (render_async &).

. На приведенном ниже снимке экрана вы можете увидеть, как запрос на самом деле сразу загружает часть его, а другие - «отложенные загрузки».Однако я заметил, что если вы измените каталог до загрузки асинхронной части, новое приглашение будет перезаписано с неверным контекстом.

enter image description here

Моя мысльПроцесс исправления этого заключается в следующем:

  • Проверка на фоновый процесс с помощью команды jobs
  • Я обнаружил, что команда jobs показывает wd:* рядом с процессами, которые не являютсяв фоновом режиме текущего рабочего каталога
  • Найти все и убить все фоновые процессы, имеющие этот шаблон, чтобы избежать перезаписи

Я добавил режим сна в свою асинхронную команду для имитации этого иЯ вижу, как фоновый процесс зависает.

[1]   Running                 render_async &
[2]-  Running                 render_async &  (wd: ~/Projects/My Personal Space/blog-core)
[3]+  Running                 render_async &

Я пошел дальше и написал:

  jobs | grep 'render_async.*wd:' | cut -d "[" -f2 | cut -d "]" -f1 | while read -r line ; do
    kill "%$line"
  done

Который в теории должен анализировать id фоновых заданий в других каталогах и уничтожать их.Однако на практике я продолжаю получать приведенный выше пример kill: %2: no such job.

Когда я выполняю ту же самую команду kill в самой оболочке, она отлично работает.

Буду признателен за любую помощь здесь.

Другие мысли

Я пытался назвать свой раздвоенный процесс (присвойте каждому асинхронному процессу имя, добавив CWD к имени функции), вдохновленный https://askubuntu.com/questions/153900/how-can-i-start-a-process-with-a-different-name где:

bash -c "exec -a MyUniqueProcessName <command> &" заменяет текущую оболочку, новый процесс не создается, поэтому я запускаю новую оболочку для вызова exec.

Затем вы можете завершить процесс с помощью:

pkill -f MyUniqueProcessName Вы можете запустить более одного процесса с одним и тем же именем, затем pkill -f убьет их всех.

, но это продолжало говорить мне, что моя асинхронная функция, которую я пытался передать<command> не найден, и я подозреваю, что это как-то связано с тем, что это пользовательская функция, которая разветвляет новый процесс bash, но я здесь не эксперт.

Спасибо

1 Ответ

0 голосов
/ 20 сентября 2018

Piping создает неявную подоболочку, поэтому задания от родителя не видны внутри цикла с конвейером по while, где выполняется kill.Как насчет этого, которое по крайней мере убьет первое задание?

job="$(jobs | grep 'render_async.*wd:' | cut -d "[" -f2 | cut -d "]" -f1)"
kill "%$job"

В моих тестах $(...) происходит в текущей оболочке, по крайней мере, на начальном этапе, поэтому таблица заданий видима.Пример:

$ cat &
[1] 8296
$ jobs
[1]+  Stopped                 cat
$ echo "$(jobs| cut -d "[" -f2 | cut -d "]" -f1|head -1)"
1

(Кстати, у задания, которое вы хотите убить, всегда есть один и тот же номер задания? Можете ли вы просто жестко кодировать %2 или что-то еще?)

Редактировать Multijob:

joblist="$(jobs| sed -E 's/^[^0-9]*([0-9]+).*$/\1/'|tr '\n' '@')"
    # E.g., 1@2@
IFS='@'     # Split on @
for job in $joblist     # No double-quotes!
do
    kill "%$job"
done

Рабочий пример из приглашения оболочки:

$ cat&
[1] 8824
$ cat&
[2] 6452

[1]+  Stopped                 cat
$ jobs
[1]-  Stopped                 cat
[2]+  Stopped                 cat
$ joblist="$(jobs| sed -E 's/^[^0-9]*([0-9]+).*$/\1/'|tr '\n' '@')"
$ IFS=@
$ for job in $joblist; do kill "%$job" ; done

[1]-  Stopped                 cat

[2]+  Stopped                 cat
$ jobs
[1]-  Terminated              cat
[2]+  Terminated              cat
$ jobs
$

Я выбрал @ в качестве разделителя, потому что я не думаю, что этоозначает что-то особенное для оболочки.

Я не знаю, имеет ли это значение в среде функции PS1.

...