Як зробити Firefox читати stdin


29
echo '<h1>hello, world</h1>' |  firefox
cat index.html | firefox

Ці команди не працюють.
Якщо Firefox може прочитати stdin, я можу надсилати html до firefox через pipe.
Чи можна змусити Firefox прочитати stdin?


2
Що саме ви хочете досягти?
пбм

6
@pbm: Можливо, буде корисно уникати зберігання тимчасових даних ...
l0b0

Відповіді:


23

Коротка відповідь - вам краще написати тимчасовий файл і відкрити його. Працювати труби належним чином складніше і, ймовірно, не дасть вам додаткових переваг. Це сказав, ось що я знайшов.

Якщо ваша firefoxкоманда насправді запускає Firefox замість розмови з уже запущеним екземпляром Firefox, ви можете зробити це:

echo '<h1>hello, world</h1>' | firefox /dev/fd/0

Це говорить про те, що Firefox чітко читає його стандартний ввід, і саме там труба вводить свої дані. Але якщо Firefox вже запущений, firefoxкоманда просто передасть це ім'я головному процесу Firefox, який прочитає власний стандартний вхід, який, ймовірно, нічого не дасть і, звичайно, не підключений до вашої труби.

Крім того, читаючи з труби, Firefox досить сильно завантажує речі, тому він не збирається оновлювати сторінку щоразу, коли ви надаєте їй новий рядок HTML, якщо для цього ви збираєтеся. Спробуйте закрити Firefox та запустити:

cat | firefox /dev/fd/0

(Зверніть увагу: вам справді потрібне catтут.) Вставте кілька довгих рядків у вікно оболонки кілька разів, поки Firefox не вирішить оновити сторінку, і ви зможете побачити, скільки даних потрібно. Тепер надішліть сигнал "Закінчення файлу", натиснувши Ctrl+Dнову лінію, і дивіться миттєве оновлення Firefox. Але тоді ви більше не можете додавати дані.

Тож найкраще, мабуть:

echo '<h1>hello, world</h1>' >my_temporary_file; firefox my_temporary_file

2
Ви можете змусити Firefox відкрити новий процес -new-instance, і це стає ... | firefox -new-instance /dev/fd/0.
чемпіон

це чудово працює, дякую! хтось знає, як це зробити замість Chrome?
Олександр Міллс

33

Ви можете використовувати URI , наприклад:

echo '<h1>hello, world</h1>' |firefox "data:text/html;base64,$(base64 -w 0 <&0)"

&0є дескриптором файлу для stdin, тому він кодує stdin до base64, потім інтерполює це в URI даних.

Цей же трюк працює і для інших браузерів:

echo '<h1>hello, world</h1>' |chromium "data:text/html;base64,$(base64 -w 0 <&0)"
echo '<h1>hello, world</h1>' |opera    "data:text/html;base64,$(base64 -w 0 <&0)"

Якщо ви хочете, ви можете помістити другу частину в сценарій bash (я буду називати це pipefox.sh):

#!/bin/bash
firefox "data:text/html;base64,$(base64 -w 0 <&0)"

Тепер ви можете зробити:

echo '<h1>hello, world</h1>' |pipefox.sh

1
абсолютно дивовижно !, як чорт ви придумали це ?. Ви можете покращити перейменування pipefox.sh на pipebrowser з контекстом: $ 1 "data: text / html; base64, $ (base64 -w 0 <& 0)", що дозволяє вибрати браузер на ваш смак
albfan

У мене є подібне запитання тут, якщо це однакова різниця, stackoverflow.com/questions/32303025/…
1.21 гігаватт

2
На жаль, це більше не працює, див. Blog.mozilla.org/security/2017/11/27/…, чому більшість міметипів у URL- адресах тепер заблоковано від навігації врівень.
TheDiveO

7

Я знайшов це:

bcat - передача утиліти браузера

... щоб встановити Ubuntu Natty, я зробив:

sudo apt-get install rubygems1.8
sudo gem install bcat
# to call
ruby -rubygems /var/lib/gems/1.8/gems/bcat-0.6.2/bin/bcat
echo "<b>test</b>" | ruby -rubygems /var/lib/gems/1.8/gems/bcat-0.6.2/bin/bcat

Я думав, що це працює з власним браузером - але запустивши вище, відкрилася нова вкладка у вже запущеному Firefox, вказуючи на адресу localhost http://127.0.0.1:53718/btest... За допомогою bcatустановки ви також можете зробити:

tail -f /var/log/syslog | ruby -rubygems /var/lib/gems/1.8/gems/bcat-0.6.2/bin/btee

... знову відкриється вкладка, але Firefox і надалі відображатиме піктограму завантаження (і, мабуть, оновить сторінку, коли оновлення системи буде оновлено).

bcatДомашній також посилається на Uzbl браузера, який , по- видимому впоратися зі стандартним вводом - але для своїх власних команд (ймовірно , слід шукати в цьому більше, хоча)


EDIT: Оскільки мені було потрібно щось подібне погано (здебільшого для перегляду таблиць HTML з даними, що генеруються під час руху (а мій Firefox стає дуже повільним, щоб бути корисним bcat), я спробував користувальницьке рішення. Оскільки я використовую ReText , у мене вже було встановлено python-qt4і WebKit прив'язки (і залежності) на моєму Ubuntu. Отже, я зібрав сценарій Python / PyQt4 / QWebKit - який працює як bcat(не подобається btee), але з власним вікном браузера - називається Qt4WebKit_singleinst_stdin.py(або qwksisiкоротко):

В основному, із завантаженим сценарієм (і залежностями) ви можете його псевдонімом в bashтерміналі, як це:

$ alias qwksisi="python /path/to/Qt4WebKit_singleinst_stdin.py"

... і в одному терміналі (після псевдоніму) qwksisiпідніме головне вікно браузера; перебуваючи в іншому терміналі (знову після псевдоніму), можна зробити наступне для отримання даних stdin:

$ echo "<h1>Hello World</h1>" | qwksisi - 

... як показано нижче:

qwksisi

Не забувайте -в кінці посилатися на stdin; в іншому випадку локальне ім'я файлу також може використовуватися як останній аргумент.

По суті, тут потрібно вирішити:

  • проблема з одним примірником (тому перший запуск скрипту стає "головним" і піднімає вікно браузера - тоді як наступні запуски просто передають дані в майстер і вихід)
  • міжпроцесовий зв'язок для обміну змінними (щоб виходили процеси могли передавати дані у головне вікно браузера)
  • Оновлення таймера в майстрі, який перевіряє наявність нового вмісту, і оновлює вікно браузера, якщо новий вміст надійшов.

Як таке, те саме можна реалізувати у, скажімо, Perl із прив'язками Gtk та WebKit (або іншим компонентом браузера). Мені цікаво, що, якби рамка XUL від Mozilla могла бути використана для реалізації тієї ж функціональності - я думаю, у цьому випадку можна було б працювати з компонентом браузера Firefox.


6

Ви можете використовувати заміну процесу :

 firefox <( echo '<h1>hello, world</h1>' )

 firefox <( cat page_header.html contents.html footer.html )

 firefox  <( echo "<h1>Hello number "{1..23}"!</h1>" )

1
Не вдається з цим працювати з Ubuntu 14.04 за допомогою bash та Firefox 29.0
John S Gruber

5

Подивіться, який пошук "stdin браузера" з'явився! , хороший маленький сценарій оболонки:

#!/bin/sh

# read from stdin, write to a temp file, open the temp file in a browser, then delete it
tmpfile=$(tempfile); cat > $tmpfile; x-www-browser $tmpfile; rm $tmpfile

Якщо ви збережете це в stdin2www, зробіть його виконуваним ( chmod +x stdin2www), ваші приклади повинні працювати через cat index.html | ./stdin2www. Просто зауважте, що відносні посилання , зображення тощо не вдасться, оскільки сторінка, що буде відкрита, - це щось /tmp/; для її виправлення знадобиться більше роботи.


3

Я написав сценарій python, щоб написати stdin у тимчасовий файл, а потім відкрити тимчасовий файл з Firefox.

#!/usr/bin/env python
import sys
import tempfile
import subprocess

with tempfile.NamedTemporaryFile() as f:
  f.write(sys.stdin.read())
  f.flush()
  process = subprocess.Popen(['firefox', f.name])
  process.wait()

0

Ви можете запустити команду нижче з сценарію оболонки / вікна терміналу.

Перед запуском Firefox (або будь-якого іншого браузера) він прочитає вміст, який відображатиметься при відкритті.

Якщо це HTML не надсилається, змініть text/htmlрядок у нижченаведеній URL-адресі на будь-який тип файлу (наприклад, text/plainабо image/png).

firefox "data:text/html;base64,$(base64)"

0

Простий ffpipeпсевдонім.

Рішення URI даних, що надаються сніжкою та luk3yx, не працюють для мене в GNU / Linux.

Наступний псевдонім повинен працювати:

alias ffpipe='base64 -w0 <&0 | read -r x; firefox "data:text/html;base64,$x"'

напр.

echo '<h1>hello, world</h1>' | ffpipe

Обмеження

Сторінка завантажується лише після закриття труби (тобто досягнуто кінця файлу).

Якщо потрібно додаткове відображення контентного контенту, вам краще скористатися чимось на зразок згаданої раніше bcatутиліти.


0

Хоча цьому питанню вже сім років, я здивований, що ніхто не запропонував рішення, що обслуговує файл через веб-сервер. Це досягається за допомогою наступного компактного сценарію Python3. Збережіть його як виконуваний файл, скажімо, browse.py:

#!/usr/bin/env python3
import sys, os, time, platform, signal
from subprocess import Popen
from http.server import HTTPServer, BaseHTTPRequestHandler
sys.stderr = open(os.devnull, 'w')
def timeoutHandler(signum, frame):
    sys.exit("")
signal.signal(signal.SIGALRM, timeoutHandler)
signal.alarm(2)
html = sys.stdin.read()
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
class Handler(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header("content-type", "text/html")
        self.end_headers()
    def do_GET(self):
        self._set_headers()
        self.wfile.write(b = bytes(html, "utf-8"))
platform = platform.system().lower()
if platform.find("win") >= 0: command = "start"
elif platform.find("mac") >= 0 or platform.find("darwin") >= 0: command = "open"
else: command = "xdg-open"
p = Popen([command, "http://localhost:" + str(port) + "/"])
httpd = HTTPServer(("localhost", port), Handler)
httpd.serve_forever()

Тоді ви можете перенаправити стандартний ввід до браузера за замовчуванням:

./browser.py < somewebpage.html
echo "<html><body><h1>Hello</h1></body></html>" | browse.py

За замовчуванням сервер працює на порту 8000, але таку поведінку можна змінити аргументом командного рядка:

./browser.py 9000 < website.html

Я перевірив цей сценарій на Linux. Він повинен працювати з іншими системами UNIX, включаючи MacOS поза коробкою. Це в принципі навіть підготовлено для Windows (у мене немає такого для тестування), але там може знадобитися реалізувати функцію тайм-ауту по-іншому.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.