Может ли Clojure захватить стандарт вне существующего процесса?

Как вы читаете в программе Clojure из стандартного вывода? Я хочу сделать это или направить стандартный вывод во входной поток, который я создаю. Стандартный вывод в Clojure — это java.io.PrintWriter .

У меня есть работа Samza, запущенная программой Clojure. Также есть сервер nrepl, к которому я могу подключиться удаленно. После подключения мне нужно иметь возможность подключиться к стандарту и выйти из него (в который задания записывают свои выходные данные).

1) В соответствии с этим вопросом SO, with-out-str (см. здесь) позволяет нам временно привязать *out*java.io.StringWriter), чтобы ваш исполняемый код записывался в строку. Но это не позволяет мне подключиться к существующему *out*.

2) Если вы посмотрите на clojure.java.shell (см. здесь), он получает среду выполнения JVM и выполняет на ней процесс. Из этого процесса вы можете получить его стандартный поток вывода. Но опять же, это не стандартный выход по умолчанию (*out*), который я ищу.

3) Этот SO вопрос приближается к тому, что я пытаюсь сделать. Но опять же, я подключаюсь к существующему процессу и хочу отключить его стандартный вывод.

Возможно ли это в Clojure (см. здесь)? Кто-нибудь решил это?


person Nutritioustim    schedule 08.11.2016    source источник
comment
В Linux вы можете читать из /proc/{pid}/fd/1, который является стандартным выводом этого процесса. Точно так же /proc/{pid}/fd/2 является stderr.   -  person Peter Lawrey    schedule 08.11.2016
comment
Вы имеете в виду, что хотите направить вывод процесса в процесс clojure, такой как ls | my-clj, и чтобы my-clj читал вывод ls? Если это так, просто используйте stackoverflow.com/questions/18688755/   -  person Alan Thompson    schedule 08.11.2016
comment
@AlanThompson Нет, я удаленно подключаюсь к реплике в уже запущенном процессе. После подключения я хочу хвост стандартного вывода.   -  person Nutritioustim    schedule 08.11.2016
comment
Я думаю, что целевой процесс должен будет перенаправить свой вывод в файл или записать непосредственно в файл журнала. Тогда вы могли бы следить за этим.   -  person Alan Thompson    schedule 08.11.2016
comment
Могу ли я предположить, что вы используете это на Linux или Mac?   -  person Arthur Ulfeldt    schedule 09.11.2016


Ответы (1)


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

Терминал 1:

cat

Терминал 2:

ps -ef | grep cat
tail -f /proc/24547/fd/2 

Терминал 1:

hello

Терминал 2: ‹ ничего >

Строка «hello», напечатанная на терминале 1, процесс, который ее запустил.

Тогда заманчиво сказать: «Ну, а если никто не прочитает вывод, тогда я смогу его получить». Хотя это звучит хорошо, но возникает проблема, заключающаяся в том, что это буферы фиксированного размера, поэтому, как только выходной буфер заполнен, процесс, который пытается записать в него, блокируется (вообще предотвращается запуск), пока кто-то не прочитает вывод, чтобы разблокировать Это.

Общее решение состоит в том, чтобы передать процесс, который вы хотите отследить позже, команде tee, которая записывает вывод в файл и передает его тому, кто его читает.

command-to-watch arg1 arg2 | tee logfile.potentially-huge

Хотя, если вы пойдете по этому пути, вы должны повернуть файл журнала до того, как ваш диск заполнится. Убедитесь, что вы очистили файл журнала именно этой командой

echo > logfile.potentially-huge

или используйте вашу программу, чтобы сделать truncate вызов файла. простое удаление файла удалит его имя из каталога журнала, не удаляя его, он будет молча продолжать расти, занимая место на диске, и новый файл никогда не будет выводиться.

Именно поэтому мы создали библиотеки журналов, такие как log4j (в 90-х) и syslog (в 80-х).

Если вы все еще хотите сходить с ума по этому поводу, обратитесь к tmux, он может делать все что угодно и меняет то, как люди работают с текстом. Со всей серьезностью вы должны изменить способ, которым другой процесс создает свой вывод, чтобы его было легче получить.

person Arthur Ulfeldt    schedule 08.11.2016