Работающий скрипт bash где-то завис.Могу ли я узнать, на какой линии он находится? - PullRequest
13 голосов
/ 09 января 2011

Например, поддерживает ли отладчик bash присоединение к существующим процессам и анализ текущего состояния?

Или я могу легко это выяснить, просмотрев записи процесса bash в / proc?Есть ли удобный инструмент для указания номеров строк в активных файлах?

Я не хочу убивать и перезапускать процесс.

Это в Linux - Ubuntu 10.04.

Ответы [ 3 ]

14 голосов
/ 25 января 2012

Я недавно оказался в подобной ситуации. У меня был сценарий оболочки, который нельзя было идентифицировать с помощью других средств (таких как аргументы и т. Д.)

Есть способы узнать о запущенном процессе намного больше, чем вы ожидаете.

Используйте lsof -p $pid, чтобы увидеть, какие файлы открыты, что может дать вам некоторые подсказки. Обратите внимание, что некоторые файлы, хотя и «удалены», все еще могут оставаться открытыми сценарием. Пока скрипт не закрывает файл, он все еще может читать и записывать из него - и файл все еще занимает место в файловой системе.

Используйте strace, чтобы активно отслеживать системные вызовы, используемые сценарием. Сценарий прочитает файл сценария, поэтому вы сможете увидеть некоторые команды в том виде, в каком они были прочитаны перед выполнением. Найдите команды read с этой командой:

strace -p $pid -s 1024

Это заставляет команды печатать строки длиной до 1024 символов (обычно команда strace будет обрезать строки намного короче).

Изучите каталог /proc/$pid, чтобы увидеть подробности о скрипте; в частности, обратите внимание на /proc/$pid/environ, который даст вам среду процесса, разделенную нулями. Чтобы правильно прочитать этот «файл», используйте следующую команду:

xargs -0 -i{} < /proc/$pid/environ

Вы можете передать это в less или сохранить в файле. Существует также /proc/$pid/cmdline, но возможно, что это даст вам только имя оболочки (например, -bash).

10 голосов
/ 09 января 2011

Нет реального решения. Но в большинстве случаев сценарий ожидает завершения дочернего процесса:

ps --ppid  $(pidof yourscript)

Вы также можете настроить обработчики сигналов в своем скрипте оболочки, чтобы переключать печать команд:

#!/bin/bash

trap "set -x" SIGUSR1
trap "set +x" SIGUSR2

while true; do
    sleep 1
done

Тогда используйте

kill -USR1 $(pidof yourscript)
kill -USR2 $(pidof yourscript)
4 голосов
/ 11 октября 2016

Используйте pstree, чтобы показать, какую команду / исполняемый файл linux вызывает ваш скрипт. Например, 21156 - это pid моего скрипта:

ocfs2cts1:~ # pstree -pl 21156
activate_discon(21156)───mpirun(15146)─┬─fillup_contig_b(15149)───sudo(15231)───chmod(15232)
                                       ├─ssh(15148)
                                       └─{mpirun}(15147)

Так что, я знаю, он зависает по команде chmod. Затем покажите трассировку стека:

ocfs2cts1:~ # cat /proc/15232/stack 
[<ffffffffa05377ef>] __ocfs2_cluster_lock.isra.39+0x1bf/0x620 [ocfs2]
[<ffffffffa053856d>] ocfs2_inode_lock_full_nested+0x12d/0x840 [ocfs2]
[<ffffffffa0538dbb>] ocfs2_inode_lock_atime+0xcb/0x170 [ocfs2]
[<ffffffffa0531e61>] ocfs2_readdir+0x41/0x1b0 [ocfs2]
[<ffffffff8120d03c>] iterate_dir+0x9c/0x110
[<ffffffff8120d453>] SyS_getdents+0x83/0xf0
[<ffffffff815e126e>] entry_SYSCALL_64_fastpath+0x12/0x6d
[<ffffffffffffffff>] 0xffffffffffffffff

О, парень, это скорее всего тупиковая ошибка ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...