Вы можете поместить inotify watch в каталог, который будет содержать файл ядра. Демонстрация:
/tmp$ { ulimit -c unlimited; exec sleep 9999; } &
[1] 25646
/tmp$ kill -QUIT %1
[1] + 25646 quit (core dumped) { ulimit -c unlimited; exec sleep 9999; }
И в другом терминале:
$ inotifywait -e close_write /tmp
Setting up watches.
Watches established.
/tmp/ CLOSE_WRITE,CLOSE core
Эта последняя строка, сообщающая о событии CLOSE_WRITE
, выдается, когда файл ядра полностью записан.
В качестве альтернативы, Linux позволяет настраивать генерацию файлов ядра. Это общесистемная настройка и требует доступа root, поэтому она может подойти или не подойти для вашего сценария. Для этого нужно установить kernel.core_pattern
ioctl, указывающий на программу, которая будет получать содержимое ядра на стандартный вывод. Игрушечная программа может быть
#!/bin/sh
cat >"/var/cores/$1-$2-$3.core"
# Do whatever you want now that the core file has been written
echo "/var/cores/$1-$2-$3.core" | mail -s "$4 dumped core" denys
в /usr/local/sbin/my_core_dumper
, зарегистрированная в
sysctl kernel.core_pattern='|/usr/local/sbin/my_core_dumper %t %P %e %E'
Патч с исправлением проблемы теперь официально включен в состав vim как патч 854 . Поэтому либо попробуйте обновиться до более новой версии vim (v8.1.0854+ ), которая включает патч, либо самостоятельно скомпилируйте из исходный код , если он еще не доступен.
xxd
использует long
для адреса, но явно усекает его до 32-битного и, кажется, нет никакого способа обойти это. Это проблема с vim #3791(спасибо за сообщение ), теперь исправлено в патче 8.1.0854 .
Однако похоже, что у него никогда не было этого ограничения на ввод (с -r
), поэтому вы можете использовать стандарт od
для печати шестнадцатеричного дампа:
od -j 0x5baae0000 -Ax -vtx1 -N16 /dev/sda
Что выведет что-то вроде:
5baae0000 2d 7c 61 76 69 76 61 72 7c 61 74 69 7a 61 72 0a
5baae0010
Однако обратите внимание, что некоторые od
реализации, в том числе GNU od
¹ не ищут для достижения смещения, указанного -j
, а считывают и пропускают все данные, что делает это непрактичным для крупноблочное устройство, как в вашем случае.
Или, если вас интересует сторона ASCII, используйте BSD hexdump
's
$ hexdump -ve '"%_ax:" 16/1 " %02x"' -e '" " 16 "%_p" "\n"' -s 0x5baae0000 -n 16 /dev/sda
5baae0000: 2d 7c 61 76 69 76 61 72 7c 61 74 69 7a 61 72 0a -|avivar|atizar
Оба из которых вы можете скормитьxxd -r
Фактически вы можете воспроизвести выходной формат xxd
(без ограничения 32-битного адреса )с hexdump
с:
hexdump -ve '"%08_ax: " 2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"" "
2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"
' -e '" " 16/1 "%_p" "\n"'
Ни od
, ни hexdump
не поддерживают эквивалент xxd
-o
для смещения адреса, но вы всегда можете опубликовать -обработку их вывода, чтобы добавить смещение к полям адреса, например,:
perl -pe 's/^\w+/sprintf "%08x", 0xabcdef + hex$&/e'
В любом случае, чтобы записать данные по определенному смещению в файл, вам не нужен xxd
, вы можете использоватьdd
:
echo HELLO | dd bs=1 seek="$((0x5baae0000))" of=/dev/sda
Илиksh93
>#((...))
поиск оператора:
echo HELLO 1<> /dev/sda >#((0x5baae0000))
или zsh
встроенный sysseek
:
zmodload zsh/system
{
sysseek -u 1 $((0x5baae0000)) &&
echo HELLO
} 1<> /dev/sda
Вы также можете использовать xxd
со смещением 0 и использовать dd/ksh93/zsh для выполнения поиска:
echo HELLO | xxd | { sysseek -u 1 $((0x5baae0000)) && xxd -r; } 1<> /dev/sda
или:
echo HELLO | xxd | { dd bs=1 seek="$((0x5baae0000))" count=0 && xxd -r; } 1<> /dev/sda
¹ Глядя на источник ,GNU od
использует fstat()
для получения размера входных данных (вместо lseek(SEEK_END)
), чтобы не искать дальше конца файла, что в таких системах, как Linux, где st_size
не отражает размер входных данных. блочное устройство не работает для блочных устройств