как заставить Firefox читать стандартный ввод


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

Эти команды не работают.
Если firefox может читать stdin, я могу отправить html в firefox через канал.
Можно ли заставить 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 не решит обновить страницу, и вы сможете увидеть, сколько данных требуется. Теперь отправьте сигнал End-Of-File, нажав 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/… , чтобы узнать, почему большинство mimetypes в 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, указывая на адрес локального хоста 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 браузера, который , по- видимому справиться со стандартным вводом - но для своих собственных команд (вероятно , следует искать в этом больше, хотя)


РЕДАКТИРОВАТЬ: Поскольку мне нужно что-то вроде этого очень сильно (в основном для просмотра таблиц 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 Framework от Mozilla мог быть использован для реализации той же функциональности - думаю, в этом случае можно было бы работать с компонентом браузера Firefox.



5

Посмотрите, что в поисках 'browser 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 для данных, предоставляемые snowball и 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.