Как я могу задержать или буферизовать поток вывода программы на несколько секунд, прежде чем он будет передан другой программе? - PullRequest
0 голосов
/ 13 июня 2019

Я хочу запустить программу, которая через несколько секунд отобразит сгенерированный URL в stderr.Я хочу взять этот URL и передать его в свой браузер.Я также хочу оставить выходные данные терминала без изменений, поэтому я использую команду tee.

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

michael@DESKTOP-OI3AOU6:~$ ./anaconda3/bin/jupyter lab ~ 2> 1.txt

michael@DESKTOP-OI3AOU6:~$ cat 1.txt
[I 12:02:11.619 NotebookApp] JupyterLab extension loaded from /home/michael/anaconda3/lib/python3.7/site-packages/jupyterlab
[I 12:02:11.620 NotebookApp] JupyterLab application directory is /home/michael/anaconda3/share/jupyter/lab
[I 12:02:11.622 NotebookApp] Serving notebooks from local directory: /home/michael/anaconda3/bin
[I 12:02:11.622 NotebookApp] The Jupyter Notebook is running at:
[I 12:02:11.622 NotebookApp] http://localhost:8888/?token=e48288141f435ebe3008ba9209d2c6d4f456a664bf6aed34
[I 12:02:11.622 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 12:02:11.631 NotebookApp]

    To access the notebook, open this file in a browser:
        file:///home/michael/.local/share/jupyter/runtime/nbserver-2069-open.html
    Or copy and paste one of these URLs:
        http://localhost:8888/?token=e48288141f435ebe3008ba9209d2c6d4f456a664bf6aed34

Тогда я могу передать это по своей цепочке так:

michael@DESKTOP-OI3AOU6:~$ cat 1.txt > >(grep ^[[:blank:]].*http.* | tr -d " \t\n\r")
michael@DESKTOP-OI3AOU6:~$ http://localhost:8888/?token=e48288141f435ebe3008ba9209d2c6d4f456a664bf6aed34

И это прекрасно работает, когда URL-адрес перенаправляется в мой браузер с настраиваемым профилем:

cat 1.txt > >(grep ^[[:blank:]].*http.* | tr -d " \t\n\r" | xargs firefox.exe -P jupyterlab 2> /dev/null)

Собирая все вместе, я получаю желаемое поведение при запуске браузераи журнал ошибок с:

michael@DESKTOP-OI3AOU6:~$ cat 1.txt > >(tee >(grep ^[[:blank:]].*http.* | tr -d " \t\n\r"| xargs firefox.exe -P jupyterlab 2>/dev/null))

michael@DESKTOP-OI3AOU6:~$ [I 12:02:11.619 NotebookApp] JupyterLab extension loaded from /home/michael/anaconda3/lib/python3.7/site-packages/jupyterlab
[I 12:02:11.620 NotebookApp] JupyterLab application directory is /home/michael/anaconda3/share/jupyter/lab
[I 12:02:11.622 NotebookApp] Serving notebooks from local directory: /home/michael/anaconda3/bin
[I 12:02:11.622 NotebookApp] The Jupyter Notebook is running at:
[I 12:02:11.622 NotebookApp] http://localhost:8888/?token=e48288141f435ebe3008ba9209d2c6d4f456a664bf6aed34
[I 12:02:11.622 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 12:02:11.631 NotebookApp]

    To access the notebook, open this file in a browser:
        file:///home/michael/.local/share/jupyter/runtime/nbserver-2069-open.html
    Or copy and paste one of these URLs:
        http://localhost:8888/?token=e48288141f435ebe3008ba9209d2c6d4f456a664bf6aed34

Проблема возникает, когда я присоединяю свою программу к каналу.Инициализация сервера и подача вывода занимает несколько секунд.Команда tr в конечном итоге просто выдвигает пустую строку в браузер, прежде чем grep получит правильную строку.

michael@DESKTOP-OI3AOU6:~$ ./anaconda3/bin/jupyter lab ~ 2> >(tee >(gre p ^[[:blank:]].*http.* | tr -d " \t\n\r"| xargs firefox.exe -P jupyterlab 2>/dev/null))

Это работает до grep, но URL будет отображаться толькочерез несколько секунд после загрузки:

michael@DESKTOP-OI3AOU6:~$ ./anaconda3/bin/jupyter lab ~ 2> >(grep ^[[:blank:]].*http.*)
        http://localhost:8888/?token=6988d45b9baa2e9f07c5a91a9a91457d6119e9884bdbcb10

Ничего не появляется после того, как я его попробую.

michael@DESKTOP-OI3AOU6:~$ ./anaconda3/bin/jupyter lab ~ 2> >(grep ^[[:blank:]].*http.* | tr -d " \t\n\r")

Как заставить команду (grep) ждатьза несколько секунд до его отправки следующей команде в цепочке потоков (tr)?

Ответы [ 2 ]

0 голосов
/ 15 июня 2019

Вы можете легко сделать трюк, подобный этому:

$ echo "hello world" | { read test && sleep 2 && echo $test; } | xargs echo
0 голосов
/ 14 июня 2019

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

michael@DESKTOP-OI3AOU6:~$ ~/anaconda3/bin/jupyter lab ~ 2> >(tee /tmp/jlab ) & sleep 4 ; cat /tmp/jlab | grep ^[[:blank:]].*http.* | tr -d " \t\n\r" | xargs firefox.exe -P jupyterlab ; rm /tmp/jlab; %

Проходя по каждой секции построчно для справки других:


~/anaconda3/bin/jupyter lab ~ & rarr; Запустите лабораторный сеанс jupyter в домашнем каталоге (~).


2> & rarr; Записать стандартную ошибку в файл, следующий за ней.


>() & rarr; Разрешить попадание каналов в файлы на стандартный ввод прилагаемой команды.

tee /tmp/jlab & rarr; Перенаправить ввод во временный файл jlab и скопировать его в стандартный вывод. Так я сохраняю поведение исходной программы, отображающей информацию в терминале. Больше информации https://en.wikipedia.org/wiki/Tee_(command)

>(tee /tmp/jlab ) & rarr; Вывод передается в команду tee


& & rarr; Разрешить процессу продолжаться в фоновом режиме.


sleep 4 & rarr; Подождите 4 секунды, чтобы сервер заработал.


; & rarr; После того, как команда выполнит следующую команду


cat /tmp/jlab & rarr; Записать содержимое временного файла / tmp / jlab в стандартный вывод.


| & rarr; Передайте стандартный вывод программы слева на стандартный ввод программы справа. В этом случае cat /tmp/jlab в grep ^[[:blank:]].*http.*.


grep ^[[:blank:]].*http.* & rarr; Извлекает строки, в начале которых есть пробел, а в строке содержится http. Это позволит любое количество символов между и после. В этом случае это работает очень хорошо, но если случайно обновление jupyter изменит выход, это то место, где оно сломается, и будет выбрано более подходящее регулярное выражение.


| вывод grep piped до tr


tr -d " \t\n\r" & rarr; Удаляет все символы табуляции и разрывы строк из строки.


| Трубы выводятся из tr в xargs. Это полный URL, уникальный для сессии jupyter.


xargs firefox.exe -P jupyterlab & rarr; Xargs берет свой стандартный ввод и передает его в качестве аргумента следующей команде.


В этом случае firefox.exe, которая является мягкой ссылкой, которую я сохранил в /usr/local/bin/firefox.exe, мягкая ссылка указывает на расположение смонтированных окон /mnt/c/, которое находится в /mnt/c/Program Files/Mozilla Firefox/Firefox.exe. Причина, по которой я монтирую его таким образом, является просто моим соглашением, поскольку исполняемые файлы Windows имеют лучшую визуализацию, чем программы, выполняемые в WSL и проходящие через xming.

-P jupyterlab & rarr; запускает созданный мной профиль, который удаляет вкладки и панель навигации из Firefox. Я также получил доступ к опции настройки в Firefox, так что заголовок показывает.

Профиль настраивается путем установки пользовательского CSS в определенном каталоге профиля %APPDATA%\Mozilla\Firefox\Profiles\

Полный путь к файлу: %APPDATA%\Mozilla\Firefox\Profiles\8vv7gs2r.jupyterlab\chrome\userChrome.css

Этот файл установит firefox, поэтому в нем не будет никаких вкладок или навигации, загромождающей окно.

Содержимое файла выглядит следующим образом:

/*
 * Do not remove the @namespace line -- it's required for correct functioning
 */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */

/*
 * Hide tab bar, navigation bar and scrollbars
 * !important may be added to force override, but not necessary
 * #content is not necessary to hide scroll bars
 */
#TabsToolbar {visibility: collapse;}
#navigator-toolbox {visibility: collapse;}

; & rarr; После того, как команда выполнит следующую команду


rm /tmp/jlab & rarr; Линия котельной пластины, которая удаляет временный файл. Обычно его следует удалять при перезагрузке системы linux, но он работает не во всех реализациях. Я не проверял, делает ли это wsl.


; & rarr; После того, как команда выполнит следующую команду


% & rarr; Перемещает последнее задание, перемещенное в фоновом режиме, с & на передний план. Программа, которая теперь выполняется, теперь будет принимать прерывания, как это было до ее перемещения в фоновый режим.

...