Как получить pid последней выполненной команды в скрипте оболочки?

254

Я хочу, чтобы скрипт оболочки был таким:

my-app &
echo $my-app-pid

Но я не знаю, как получить pid только что выполненной команды.

Я знаю, что могу просто использовать jobs -p my-appкоманду для grep pid. Но если я хочу выполнить оболочку несколько раз, этот метод не будет работать. Потому что задание на работу неоднозначно.

Дэвид С.
источник

Ответы:

338

PID последней выполненной команды находится в $!переменной оболочки:

my-app &
echo $!
enzotib
источник
1
Это печатный пид как например. [1] 893. Я хочу только номер.
user3153014
33
Следует отметить, что это означает программы, запущенные в фоновом режиме . Если фоновые процессы не были запущены, параметр не устанавливается.
ramrunner
5
Еще одно достойное решение предлагается в (комментарий к ответу) Как получить pid только что начавшегося процесса : о, и "oneliner": /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &- sysfault 24 ноября 2010 г. в 14:28
imz - Иван Захарящев
14
@ user3153014 Строки типа "[2] 2625" печатаются оболочкой после запуска фоновой задачи. Это не связано с выходомecho $!
Петр Гладких
Я обычно использую такой код в скрипте, когда мне нужно дождаться окончания процесса. my-app & myVar=$! ; fg, fgвыводит процесс на первый план снова. Затем я могу распечатать echo $myVarпозже, и я почти уверен, что мое приложение уже завершено.
Врата Блазек
66

Получить PID:

#!/bin/bash
my-app &
echo $!

Сохранить PIDв переменной:

#!/bin/bash
my-app &
export APP_PID=$!

Сохраните все экземпляры PIDв текстовом файле:

#!/bin/bash
my-app &
echo $! >>/tmp/my-app.pid

Сохранить вывод, ошибки и PIDв отдельных файлах:

#!/bin/bash
my-app >/tmp/my-app.log 2>/tmp/my-app.error.log &
echo $! >>/tmp/my-app.pid

echo "my-app PID's: $(cat /tmp/my-app.pid)"
Эдуардо Куомо
источник
3
Вопрос не задавал вопрос о перенаправлении, тогда ваш ответ в основном совпадает с принятым, за исключением того, что если экземпляр my-appзаканчивается, и, возможно, еще хуже, его PID будет повторно использован позже, у вас будет неверная информация в вашем файле. Я не думаю, что этот ответ добавляет большую ценность существующему принятому ответу на самом деле
Эрик Ренуф
@EricRenouf сообщение обновлено!
Эдуардо Куомо
другая производная, которая может быть полезной. Это получает PID и в то же время рассматривает его как (в основном) процесс переднего плана: sleep 4 | grep INVALID & export MY_PID=$!; fg; echo $MY_PID returned with $?`
mlathe
APP = main &способ получить PID?
MrMesees
3

Попробуйте что-то вроде

pidof my_app >> /tmp/my_app.pid
Пиюш Джайн
источник
1
внешняя команда и медленная, если система может дать PID напрямую, зачем искать во всех процессах именно это? а также, не могу быть уверен, что вы получите правильное значение
папа
-4

Попробуйте что-то вроде этого:

 ps ef | grep "[m]y-app" | awk '{print $2}'

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

Goez
источник
9
Это в лучшем случае очень хрупко и не работает, если my-appвыполняется более одного раза - davidshen84 особенно беспокоится об этом.
Мат
2
Если вы даже идете по этому пути, вы должны использовать pgrepвместо этого.
Виллем