Программы не отображаются в заданиях, если я запускаю их в фоновом режиме с помощью сценария оболочки.

Я хочу запустить три программы (2x streamlit, 1x python) в фоновом режиме с помощью сценария оболочки:

#!/bin/sh
cd /Users/mc/src/crypto/ || exit
streamlit run dashboard.py &
streamlit run dashboard_basis_viewer.py &
/Users/mc/.virtualenvs/crypto/bin/python basis_calculator.py &

Этот скрипт работает (т.е. программы запускаются нормально), но есть две проблемы:

  1. Ни один из процессов не отображается под jobsкомандой
  2. Если я закрываю терминал (iTerm), все эти процессы продолжают работать.

Если я запускаю последние 3 строки вручную из командной строки, у меня не возникает ни одной из этих проблем. Что тут происходит? Как я могу это исправить?

Скрипт делает именно то, что вы пишете в первой строке, не уверен, что ваш вопрос здесь. Что вы хотите сделать в конце (или, другими словами, что именно нужно исправить и как это должно выглядеть/вести себя)?
@nohillside Я думаю, что процессы, которые я запускаю, должны отображаться внизу jobs, и эти процессы должны быть убиты, если я выйду из терминала. Это поведение, если бы я запускал процессы в командной строке, а не из сценария.
AFAIK jobsне показывает фоновые процессы, запущенные из сценариев (только те, которые вы запустили в интерактивном режиме в текущей оболочке).
Вместо ввода ./myscriptпопробуйте source ./myscriptили . ./myscript.

Ответы (1)

Что тут происходит?

У вас есть процесс, запускающий оболочку. Основываясь на информации, указанной в опубликованном вопросе, делается предположение, что это zsh, но возможны и другие. Когда опубликованный скрипт выполняется, создается новый процесс для запуска скрипта в файле /bin/sh. Этот новый процесс запускает три новых фоновых задания, связанных с /bin/sh. Затем /bin/shзавершается, оставляя три задания в виде осиротевших процессов. Таким образом, при jobsвводе команды эти три задания не появляются, потому что три теперь осиротевших процесса никогда не были заданиями исходного файла zsh. Более того, при zshзавершении трем заданиям не посылаются никакие сигналы типа завершения, поскольку процессы являются осиротевшими.

Как я могу это исправить?

Если необходимо, чтобы при jobsвводе команды отображались три задания, то перед путем и именем сценария может стоять команда .или . sourceСкрипт будет выполняться в текущем zshи поэтому первая строка в размещенном скрипте будет проигнорирована. Например, если имя сценария есть myscriptи находится в текущем рабочем каталоге, то можно ввести одно из следующего.

. ./myscript
source ./myscript 

Если нет необходимости, чтобы три задания появлялись при jobsвводе команды, тогда строка, содержащая waitкоманду, может быть добавлена ​​к опубликованному сценарию. Это предотвратит создание сирот, когда для выполнения сценария в фоновом режиме используется следующее.

./myscript &

Наконец, от идеи сценария можно отказаться в пользу функции. Ниже приведен пример.

myfunction()
{
    local "cwd=$(pwd)"
    cd /Users/mc/src/crypto/
    local "n=$?"
    if [[ n -eq 0 ]]; then 
        streamlit run dashboard.py &
        streamlit run dashboard_basis_viewer.py &
        /Users/mc/.virtualenvs/crypto/bin/python basis_calculator.py &
        n="$?"
    fi
    cd "$cwd"
    return "$n"
}

 

Фантастический ответ. Хотя, если я могу задать краткий вопрос, чтобы уточнить... Я знаю, что и то, и другое .имеет sourceтот же результат... но только большую часть времени, по крайней мере, в моей системе по моему опыту. Если я пытаюсь получить сценарий, используя .псевдоним из подоболочки в другом сценарии, это не удается. sourceРаботает только команда. Я всегда предполагал, что это произошло из-за того, что псевдоним не был установлен в глобальной области видимости, а подоболочка не загружала мой .bash_profile/.bashrc/etc.. но, читая ваш ответ, меня осенило, что я только что предполагал что все эти годы. Я близко?