cómo hacer que Firefox lea stdin

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

Estos comandos no funcionan.
Si firefox puede leer stdin, puedo enviar html a firefox a través de pipe.
¿Es posible hacer que Firefox lea stdin?

kev
fuente
2
¿Qué es exactamente lo que quieres lograr?
pbm
66
@pbm: Puede ser útil evitar almacenar datos temporales ...
l0b0

Respuestas:

23

La respuesta corta es que es mejor escribir un archivo temporal y abrirlo. Hacer que las tuberías funcionen correctamente es más complicado y probablemente no le dará ninguna ventaja adicional. Dicho esto, esto es lo que he encontrado.

Si su firefoxcomando realmente está iniciando Firefox en lugar de hablar con una instancia de Firefox que ya se está ejecutando, puede hacer esto:

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

Lo que le dice a Firefox explícitamente que lea su entrada estándar, que es donde la tubería coloca sus datos. Pero si Firefox ya se está ejecutando, el firefoxcomando simplemente pasará ese nombre al proceso principal de Firefox, que leerá su propia entrada estándar, que probablemente no le dará nada y ciertamente no está conectado a su tubería.

Además, al leer desde una tubería, Firefox amortigua bastante las cosas, por lo que no va a actualizar la página cada vez que le proporcione una nueva línea de HTML, si eso es lo que está buscando. Intenta cerrar Firefox y ejecuta:

cat | firefox /dev/fd/0

(Nota: realmente necesitas el cataquí). Pega algunas líneas largas en tu ventana de shell varias veces hasta que Firefox decida actualizar la página y puedas ver cuántos datos se necesitan. Ahora envíe una señal de fin de archivo presionando Ctrl+Den una nueva línea y vea la actualización de Firefox al instante. Pero entonces no puede agregar más datos.

Entonces lo mejor es probablemente:

echo '<h1>hello, world</h1>' >my_temporary_file; firefox my_temporary_file
Jander
fuente
2
Puede forzar a Firefox a abrir un nuevo proceso -new-instance, por lo que se convierte en ... | firefox -new-instance /dev/fd/0.
rampion
esto funciona muy bien, gracias! ¿Alguien sabe cómo hacer esto con Chrome?
Alexander Mills el
33

Puede usar URI de datos , como este:

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

&0es el descriptor de archivo para stdin, por lo que codifica stdin en base64, luego lo interpola en el URI de datos.

El mismo truco también funciona para otros navegadores:

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)"

Si lo desea, puede poner la segunda parte en un script bash (lo llamaré pipefox.sh):

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

Ahora puedes hacer:

echo '<h1>hello, world</h1>' |pipefox.sh
Bola de nieve
fuente
1
totalmente increíble !, ¿Cómo diablos se te ocurrió esto? Puede mejorar el cambio de nombre de pipefox.sh a pipebrowser con el contexto: $ 1 "data: text / html; base64, $ (base64 -w 0 <& 0)" permitiendo elegir el navegador a su gusto
albfan
Tengo una pregunta similar aquí si es la misma diferencia, stackoverflow.com/questions/32303025/…
1.21 gigavatios
2
Desafortunadamente, esto ya no funciona, vea blog.mozilla.org/security/2017/11/27/… para ver por qué la mayoría de los tipos MIME en las URL de datos ahora están bloqueados de la navegación de nivel superior.
TheDiveO
7

Encontré esto:

bcat - utilidad de canalización a navegador

... para instalar en Ubuntu Natty, hice:

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

Pensé que funciona con su propio navegador, pero al ejecutar lo anterior se abrió una nueva pestaña en un Firefox que ya se estaba ejecutando, apuntando a una dirección de host local http://127.0.0.1:53718/btest... Con la bcatinstalación también puede hacer:

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

... se abrirá nuevamente una pestaña, pero Firefox seguirá mostrando el ícono de carga (y aparentemente actualizará la página cuando se actualice Syslog).

La bcatpágina de inicio también hace referencia al navegador uzbl , que aparentemente puede manejar stdin, pero para sus propios comandos (aunque probablemente debería investigar esto más)


EDITAR: como necesitaba mucho algo como esto (principalmente para ver tablas HTML con datos generados sobre la marcha (y mi Firefox se está volviendo muy lento para ser útil bcat), probé con una solución personalizada. Como uso ReText , ya tenía instalado python-qt4y enlaces de WebKit (y dependencias) en mi Ubuntu. Entonces, armé un script Python / PyQt4 / QWebKit, que funciona como bcat(no como btee), pero con su propia ventana del navegador, llamado Qt4WebKit_singleinst_stdin.py(o qwksisipara abreviar):

Básicamente, con el script descargado (y las dependencias) puede alias en un bashterminal como este:

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

... y en un terminal (después del alias), qwksisiabrirá la ventana del navegador maestro; mientras que en otra terminal (nuevamente después de alias), uno podría hacer lo siguiente para obtener datos stdin:

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

... Como se muestra abajo:

qwksisi

No olvides -al final para referirte a stdin; de lo contrario, también se puede usar un nombre de archivo local como último argumento.

Básicamente, el problema aquí es resolver:

  • problema de instancia única (por lo que la primera ejecución del script se convierte en un "maestro" y abre una ventana del navegador, mientras que las ejecuciones posteriores simplemente pasan los datos al maestro y salen)
  • Comunicación entre procesos para compartir variables (para que los procesos que salen puedan pasar datos a la ventana del navegador maestro)
  • Actualización del temporizador en el maestro que verifica si hay contenido nuevo y actualiza la ventana del navegador si llega contenido nuevo.

Como tal, lo mismo podría implementarse en, por ejemplo, Perl con enlaces Gtk y WebKit (u otro componente del navegador). Sin embargo, me pregunto si el marco XUL de Mozilla podría usarse para implementar la misma funcionalidad; supongo que en ese caso, uno funcionaría con el componente del navegador Firefox.

sdaau
fuente
6

Puede usar la sustitución de procesos :

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

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

 firefox  <( echo "<h1>Hello number "{1..23}"!</h1>" )
rozcietrzewiacz
fuente
1
No puedo hacer que funcionen con Ubuntu 14.04 usando bash y Firefox 29.0
John S Gruber
5

¡Mira qué búsqueda de 'navegador stdin' apareció! , un pequeño script de shell:

#!/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

Si guarda esto stdin2www, hágalo ejecutable ( chmod +x stdin2www), sus ejemplos deberían funcionar a través de cat index.html | ./stdin2www. Solo tenga en cuenta que los enlaces relativos , imágenes, etc., fallarán ya que la página que se abrirá es algo /tmp/; Se necesitaría más trabajo para solucionar esto.

sr_
fuente
3

Escribí un script de Python para escribir stdin en un archivo temporal y luego abrir el archivo temporal con 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()
Tom
fuente
0

Puede ejecutar el siguiente comando desde un script de shell / ventana de terminal.

Antes de iniciar Firefox (o cualquier otro navegador), leerá de su contenido estándar para mostrar al abrir.

Si no se está enviando HTML, cambie la text/htmlcadena en la siguiente URL a cualquier tipo de archivo (por ejemplo, text/plaino image/png).

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

Un simple ffpipealias.

Las soluciones URI de datos proporcionadas por snowball y luk3yx no me funcionan en GNU / Linux.

El siguiente alias debería funcionar:

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

p.ej.

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

Limitaciones

La página solo se cargará una vez que se cierre la tubería (es decir, se haya alcanzado el final del archivo).

Si se requiere una representación incremental del contenido canalizado, es mejor que use algo como la bcatutilidad mencionada anteriormente .

pirocrastia
fuente
0

Aunque esta pregunta tiene siete años, me sorprende que nadie haya propuesto una solución que sirva el archivo a través de un servidor web. Esto se logra con el siguiente script compacto de Python3. Guárdelo como un archivo ejecutable, por ejemplo, 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()

Luego puede redirigir la entrada estándar al navegador predeterminado:

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

Por defecto, el servidor funciona en el puerto 8000, pero ese comportamiento se puede cambiar con un argumento de línea de comando:

./browser.py 9000 < website.html

Probé este script en Linux. Debe manejar otros sistemas UNIX, incluido MacOS, de fábrica. En principio, incluso está preparado para Windows (no tengo uno para probar), pero allí puede ser necesario implementar la funcionalidad de tiempo de espera de manera diferente.

tglas
fuente