У меня есть приложение, которое выполняет команду как указано ниже:
<command> <switches> >& /dev/null
Я могу настроить <command>
, но я не имею никакого контроля <switches>
. Весь вывод, сгенерированный этой командой, переходит в /dev/null
. Я хочу, чтобы вывод был видим на экране или перенаправленный к файлу журнала.
Я пытался использовать freopen()
и связанные функции для повторного открытия /dev/null
в другой файл, но не мог получить его работа.
У Вас есть какие-либо другие идеи? Действительно ли это возможно вообще?
Спасибо за внимание.
PS: Я работаю над Linux.
Поскольку вы можете изменять выполняемую команду, вы можете использовать простой сценарий оболочки в качестве оболочки для перенаправления вывода в файл.
#!/bin/bash
"$@" >> logfile
Если вы сохраните это в своем пути как capture_output.sh, вы можете добавить capture_output.sh в начало вашей команды, чтобы добавить вывод вашей программы в файл журнала.
Ужасный взлом:
используйте текстовый редактор в двоичном режиме, откройте приложение, найдите '/ dev / null /' и замените его строкой такой же длины
e.g '~/tmp/log'
Добавьте #
в конец вашей команды, чтобы она стала
, таким образом закомментировав нежелательную часть.
Файл устройства / dev / tty
ссылается на управляющий терминал вашего приложения - если он не изменился, то это должно работать:
freopen("/dev/tty", "w", stdout);
freopen("/dev/tty", "w", stderr);
Кроме того, вы можете повторно открыть их, чтобы указать на файл журнала:
freopen("/var/log/myapp.log", "a", stdout);
freopen("/var/log/myapp.err", "a", stderr);
Вы можете сделать это с уже запущенным процессом, используя gdb. См. Следующую страницу: http://etbe.coker.com.au/2008/02/27/redirecting-output-from-a-running-process/
Можете ли вы создать псевдоним для этой команды? Если это так, присвойте ему псевдоним другой команде, которая выводит вывод в файл.
РЕДАКТИРОВАТЬ: Это НЕ хорошая идея и, конечно, не стоит пытаться, если вы не знаете, что это может сломать. Это работает для меня, может сработать и для вас.
Хорошо, это действительно плохой хакер, и, вероятно, его не стоит делать. Предполагая, что ни одна из других команд не работает, и у вас просто нет доступа к двоичному файлу / приложению (которое содержит команду с / dev / null
), и вы не можете перенаправить вывод в другой файл ( путем замены / dev / null
).
Затем вы можете удалить / dev / null ( $> rm / dev / null
) и создать свой собственный файл на его месте (желательно с мягкой ссылкой), куда можно направить все данные. Когда вы закончите, вы можете снова создать / dev / null, используя следующую команду:
$> mknod -m 666 / dev / null c 1 3
Для ясности, это a плохой хак и, конечно же, для работы требуются права root . Высокие шансы, что ваш перенаправленный файл может содержать данные из многих других приложений / двоичных файлов, которые работают и используют / dev / null
в качестве приемника.
Ваше приложение, вероятно, запускает оболочку и передает ей эту командную строку.
Вам нужно заставить его запускать написанный вами скрипт. Этот сценарий заменит > / dev / null
в командной строке на >> / your / log
и вызовет реальную оболочку с измененной командной строкой.
Первым шагом является изменение оболочки, используемой приложением. Достаточно изменить переменную среды SHELL
, т. Е. Запустите приложение как
SHELL=/home/user/bin/myshell theApp
. Если это не сработает, попробуйте на мгновение связать / bin / sh
со своим скриптом.
myshell
вызовет исходную оболочку, но после замены параметров шаблоном:
#!/bin/bash
sh ${1+"${@/\>\/dev\/null/>>\/your\/log}"}
Что-то в этом роде должно работать.
В Perl, если вы просто хотите перенаправить STDOUT
на что-то более полезное, вы можете просто сделать что-то вроде:
open STDOUT, '>>', '/var/log/myscript.log';
open STDERR, '>>', '/var/log/myscript.err';
в начале вашего скрипта, и это перенаправит его для остальной части вашего скрипта.
В соответствии со строками ответа e-t172, можете ли вы установить последний переключатель в положение (или добавить к нему):
; echo
Возможно, он не совсем перенаправлен, но он позволяет получать результат, куда бы он ни отправлялся
strace -ewrite -p $ PID
Это не так чисто (показывает строки вроде: write (#,)), но работает! (и однострочный: D) Вам также может не понравиться тот факт, что аргументы сокращены. Чтобы управлять этим, используйте параметр -s, который устанавливает максимальную длину отображаемых строк.
Он улавливает все потоки, поэтому вы можете как-то их отфильтровать.
Вы можете отфильтровать его:
strace -ewrite -p $ PID 2> & 1 | grep "write (1"
показывает только вызовы дескриптора 1. 2> & 1 перенаправляет stderr на stdout, поскольку strace по умолчанию записывает в stderr.
Если вы можете поместить что-то в строку перед передачей в /dev/null (не уверен, что вы имеете дело с жестко закодированной командой), вы можете использовать tee для перенаправления на что-то по вашему выбору.
Пример из Википедии, позволяющий эскалацию команды:
echo "Body of file..." | sudo tee root_owned_file > /dev/null