Получение PID из фонового процесса, запущенного от имени другого пользователя - PullRequest
6 голосов
/ 01 июня 2011

Получить идентификатор фонового процесса легко из приглашения:Теперь, как я могу захватить PID my_daemon?

Ответы [ 4 ]

13 голосов
/ 01 июня 2011

Кратко - с большой сложностью.

Вы должны договориться, чтобы оболочка su'd записывала дочерний PID в файл, а затем выбирала вывод.Учитывая, что создание файла будет «joe», а не «dex», это добавляет еще один уровень сложности.

Возможно, самое простое решение:

su - joe -c "/path/to/my_daemon & echo \$! > /tmp/su.joe.$$"
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$   # Probably fails - joe owns it, dex does not

Следующее решение предполагает использованиезапасной дескриптор файла - номер 3.

su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>/tmp/su.joe.$$
bg=$(</tmp/su.joe.$$)
rm -f /tmp/su.joe.$$

Если вы беспокоитесь о прерываниях и т. д. (и, вероятно, должны это делать), то вы тоже перехватываете вещи:

tmp=/tmp/su.joe.$$
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
su - joe -c "/path/to/my_daemon 3>&- & echo \$! 1>&3" 3>$tmp
bg=$(<$tmp)
rm -f $tmp
trap 0 1 2 3 13 15

(пойманные сигналы: HUP, INT, QUIT, PIPE и TERM - плюс 0 для выхода из оболочки.)

Предупреждение: хорошая теория - непроверенный код ...

1 голос
/ 05 февраля 2016

Подходы, представленные здесь, не работают для меня.Вот что я сделал:

PID_FILE=/tmp/service_pid_file
su -m $SERVICE_USER -s /bin/bash -c "/path/to/executable $ARGS >/dev/null 2>&1 & echo \$! >$PID_FILE"
PID=`cat $PID_FILE`
0 голосов
/ 12 апреля 2013

Я использовал вышеприведенное решение в Linux, но мне пришлось добавить режим сна, чтобы дать возможность дочернему процессу запускаться.

su - joe -c "/path/to/my_daemon > /some/output/file" &
parent=$!
sleep 1
pid=$(pgrep -P $parent)

Запуск в bash, ему не нравится pid=$(pgrep -P $!), но еслиЯ добавляю пробел после ! все нормально: pid=$(pgrep -P $! ).Я застрял с дополнительной переменной $parent, чтобы напомнить себе, что я делаю в следующий раз, когда я смотрю на сценарий.

0 голосов
/ 11 января 2013

Вот мое решение

su oracle -c "/home/oracle/database/runInstaller" &
pid=$(pgrep -P $!)

Эксплантация

  • pgrep -P $! - получает дочерний процесс родительского pid $!
...