В системе ELF базовый файл является почти наверняка допустимым файлом ELF.
$ readelf -a core
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: CORE (Core file)
Machine: Intel 80386
[...]
Платформа определенное количество "примечаний" добавляется к сегменту NOTES так, чтобы отладчик мог найти свой путь вокруг, например, для Соляриса, видит ядро (4), и Вы отметите NT_UTSNAME
структура, которая содержит структуру данных от uname(2)
syscall. elfdump -n
путь состоит в том, чтобы считать, что, но насколько я знаю, Солярисом является единственная ОС, которая делает это (и я подозреваю только Солярис 11 elfdump
работы, как надеялся).
Простое, хотя немного трудный и не - гарантируемый путь должен попытаться ловить рыбу HOST
или HOSTNAME
переменные (установленный некоторыми сценариями запуска и оболочками, bash
по крайней мере, наборы HOSTNAME
) из среды дампа ядра. Можно сделать это с gdb
, хотя Вам нужен исходный двоичный файл:
$ gdb /usr/bin/sleep core
[... snip ...]
(gdb) print (char ***) &environ
$1 = (char ***) 0x600bf8
(gdb) print $1[0][0]@10
$2 = {0x7fffffffd9c9 "HOST=myhostname", 0x7fffffffd9d9 "TERM=screen",
0x7fffffffd9e5 "SHELL=/bin/csh",
[...]
Это печатает блок строк от environ
символ. Хотя это - ужасный взлом strings | grep HOSTNAME=
просто мог бы работать также.
Так, короткий ответ на "Является там способом узнать, какой хост генерировал тот базовый файл": не легко, и не надежно на Linux.
FWIW, соответствующий код coredump Linux находится в fs/binfmt_elf.c
, и существует рычаг для разрешения дополнительных "примечаний" посредством ARCH_HAVE_EXTRA_ELF_NOTES
, в настоящее время только используемый на PowerPC.)
Лучший план в целом состоит в том, чтобы использовать sysctl для установки базового имени файла на каждом клиенте, как предложено @jlliagre:
sysctl kernel.core_pattern="%h-%t-%e.core"
(sysctl
и рыться вокруг в /proc
эквивалентны здесь, я предпочитаю sysctl
так как изменения могут быть сохранены зарегистрированными в /etc/sysctl.conf
и это используется на *системы BSD также.)
Как в последнее время вы можете переопределить его сразу с Bash
. Ваш . Профиль
может начать с
read -r cmd rest < <(cat /proc/$$/cmdline | tr '\000' ' ')
if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then
exec /bin/bash "$rest"
fi
#... the rest of the .profile script
Я считаю, что он должен работать. Проверьте это немного.
Отредактируйте:
Предыдущая версия не работает, потому что $ 0
не является Bash, который запускает скрипт, но обычно имя сценария, а $ @
не Включите имя сценария, который работает. Вот почему оригинальная командная линия получена из proc
, чтобы на самом деле полностью воспроизвести командную строку, но с первым аргументом (оболочкой) заменена на Bash, если это еще не Bash
(удалить Если
, и у вас бесконечная рекурсия).
Неуклюженое чтение выполняется, потому что Proc
использует разделители нуля символов вместо пробелов и, таким образом, затрудняет нашу жизнь. Но не важно.
Родительская оболочка перезаписывается, как агент Смит перезаписывает людей в матрицу. Больше нет тире
. PID Dash
и все в нем захватывается Bash
. Новый Bash
Reruns скрипт (но на этот раз доходит до конца).
Я вспоминаю, что .profile
не передается как аргумент для Bash, но выполняется во время самой инициализации (источника). Вы должны внимательно просмотреть вашу конкретную ситуацию. Может быть, лучше на самом деле принуждать Exec / Bin / Bash --login
, чтобы избежать хлопот с чтением командной строки. Затем входной оболочку следует прочитать .profile
в любом случае.
Поэтому окончательное предложение просто поставлено
if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then
exec /bin/bash --login
fi
в ваш .profile
в начале и посмотреть, что происходит. В идеале это не должно иметь никакой разницы.