Linux: Как узнать, где был запущен процесс и как он был запущен?

34

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

Когда я нажал c , чтобы просмотреть командную строку, он показал / var / spool / mail. Что не имеет смысла, так как это каталог.

Мои вопросы:

1) Почему это произошло? Как этот процесс Perl может маскировать свою командную строку? 2) Какой самый надежный способ узнать, где и как был запущен процесс?

Благодарность!

Фернандо
источник

Ответы:

36

В большинстве случаев достаточно просто запустить psвместе с вашими любимыми флагами, чтобы обеспечить широкий вывод. Я склоняюсь к ps -feww, но другие предложения здесь будут работать. Обратите внимание, что если программа была запущена кем-то другим $PATH, вы увидите только имя исполняемого файла, а не полный путь. Например, попробуйте это:

$ lftp &
$ ps -feww | grep ftp
lars      9600  9504  0 11:30 pts/10   00:00:00 lftp
lars      9620  9504  0 11:31 pts/10   00:00:00 grep ftp

Важно отметить, что отображаемая информация psможет быть полностью перезаписана запущенной программой. Например, этот код:

int main (int argc, char **argv) {
        memset(argv[0], ' ', strlen(argv[0]));
        strcpy(argv[0], "foobar");
        sleep(30);
        return(0);
}

Если я скомпилирую это в файл с именем «myprogram» и запусту его:

$ gcc -o myprogram myprogram.c
$ ./myprogram &
[1] 10201

А затем запустите ps, я увижу другое имя процесса:

$ ps -f -p 10201
UID        PID  PPID  C STIME TTY          TIME CMD
lars     10201  9734  0 11:37 pts/10   00:00:00 foobar

Вы также можете посмотреть непосредственно /proc/<pid>/exe, который может быть символической ссылкой на соответствующий исполняемый файл. В приведенном выше примере это дает вам гораздо больше полезной информации, чем ps:

$ls -l /proc/9600/exe
lrwxrwxrwx. 1 lars lars 0 Feb  8 11:31 /proc/9600/exe -> /usr/bin/lftp
larsks
источник
1
В общем, все файлы в /procпредоставят всю информацию о программе, exeбудут ссылкой на исполняемый файл, cwdна текущий рабочий каталог, fdкаталог содержит ссылки на открытые файлы (включая стандартный ввод, вывод и стандартную ошибку)
Hubert Kario
57

Самый надежный способ - взглянуть на /procкаталог процесса. Каждый процесс имеет /proc/<pid>/каталог, в котором хранится такая информация, как:

  1. cwd ссылка на текущий рабочий каталог
  2. fd каталог со ссылками на открытые файлы (файловые дескрипторы)
  3. cmdline прочитайте его, чтобы увидеть, какая командная строка была использована для запуска процесса
  4. environ переменные среды для этого процесса
  5. root ссылка на то, что процесс считает своим корневым каталогом (он будет / если не будет изолирован)

Есть более крутая информация о каждом процессе / процессе, но с этими выше вы сможете точно знать, что происходит.

Кроме того, использование ps auxfпокажет вам, кто разветвляется, и вы сможете лучше понять, кто вызывает ваш Perl.

CoreDump
источник
Я всегда использую Process Explorer в Windows и спрашиваю себя, существует ли аналог в Linux. Этот переключатель делает все это! ps auxf ... приятно!
Яник Жируард
1
+1 для параметра f для ps, который сделал это для меня!
Леннарт Роллан
2
+1 за то, что научил меня тому, что кажется таким фундаментальным понятием ... /procсодержит информацию о процессе! кто знал?? все, что я когда-либо искал там, было versionи cpuinfoвсе такое ... плюс это решает мою реальную проблему, потому что версия моего маршрутизатора ps игнорирует все параметры
Nacht - Восстановите Monica
@coredump: и если процесс вызывался chroot()раньше, как я могу узнать, какой каталог /proc/ᴘɪᴅ/cwdсоответствует?
user2284570
10

для меня, только сейчас, я обнаружил, что pstreeдал гораздо более четкое представление о том, как процесс был запущен, чемps aux

это выглядит так:

  ├─lightdm─┬─Xorg
  │         ├─lightdm─┬─init─┬─apache2───2*[apache2───26*[{apache2}]]
  │         │         │      ├─at-spi-bus-laun─┬─dbus-daemon
  │         │         │      │                 └─3*[{at-spi-bus-laun}]
  │         │         │      ├─at-spi2-registr───{at-spi2-registr}
  │         │         │      ├─dbus-daemon
  │         │         │      ├─dropbox───29*[{dropbox} ]
бесконечномерным и т.д.
источник
2

Попробуйте ps axww | grep perlполучить полную командную строку вашего процесса. Похоже, topтолько что обрезал длинную линию.

Alex
источник
2

Попробуйте использовать команду fuser -vu /var/spool/mail Эта команда покажет вам PID процессов, использующих указанные файлы или файловые системы. В режиме отображения по умолчанию за каждым именем файла следует буква, обозначающая тип доступа:

c - текущий каталог. e - исполняемый файл запускается. f - открыть файл. f опускается в режиме отображения по умолчанию. r - корневой каталог. m - файл mmap или общая библиотека.

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

panaroik
источник
1

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

Джейсон Тан
источник
1

На ум приходят две команды:

1) получить время начала процесса из « ps ».

$ ps -ax -o pid,start,comm
  PID  STARTED COMMAND         USER
    1   Feb 06 init            root
    2   Feb 06 kthreadd        root
[...]
  13147 19:09:48 chrome          hcooper
  13270 19:13:51 chrome          hcooper
  13386 19:18:34 bash            hcooper

2) lastcomm , который я сейчас проверяю, я не установил. Во всяком случае, описание страницы руководства говорит:

   lastcomm prints out information about previously executed commands. If
   no arguments are specified, lastcomm will print info about all of the
   commands in acct (the record file).

Но, как говорили несколько человек, «ls -al / proc /» скажет вам многое!

Coops
источник
0

вы можете использовать:

systemctl status <PID>

или с именем процесса:

systemctl status $(pgrep perl)

Это предоставит информацию о системных службах, которые запустили ваш процесс.

Я нашел этот намек здесь

TVK
источник