comment faire pour lire Firefox stdin

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

Ces commandes ne fonctionnent pas.
Si firefox peut lire stdin, je peux envoyer du html à firefox via pipe.
Est-il possible de faire lire Firefox à stdin?

kev
la source
2
Que voulez-vous exactement accomplir?
pbm
6
@pbm: Il pourrait être utile d'éviter de stocker des données temporaires ...
l0b0

Réponses:

23

La réponse courte est qu'il vaut mieux écrire un fichier temporaire et l'ouvrir. Faire fonctionner les tuyaux correctement est plus compliqué et ne vous donnera probablement aucun avantage supplémentaire. Cela dit, voici ce que j'ai trouvé.

Si votre firefoxcommande démarre réellement Firefox au lieu de parler avec une instance de Firefox déjà en cours d'exécution, vous pouvez le faire:

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

Ce qui dit à Firefox de lire explicitement son entrée standard, qui est l'endroit où le tuyau place ses données. Mais si Firefox est déjà en cours d'exécution, la firefoxcommande va simplement passer ce nom au processus principal de Firefox, qui lira sa propre entrée standard, qui ne lui donnera probablement rien et n'est certainement pas connecté à votre pipe.

De plus, lors de la lecture à partir d'un canal, Firefox met en mémoire tampon les choses assez lourdement, donc il ne va pas mettre à jour la page chaque fois que vous lui donnez une nouvelle ligne de HTML, si c'est ce que vous recherchez. Essayez de fermer Firefox et de lancer:

cat | firefox /dev/fd/0

(NB vous en avez vraiment besoin catici.) Collez plusieurs longues lignes dans votre fenêtre shell jusqu'à ce que Firefox décide de mettre à jour la page, et vous pouvez voir combien de données cela prend. Envoyez maintenant un signal de fin de fichier en frappant Ctrl+Dsur une nouvelle ligne et regardez Firefox se mettre à jour instantanément. Mais alors vous ne pouvez plus ajouter de données.

Le mieux est donc probablement:

echo '<h1>hello, world</h1>' >my_temporary_file; firefox my_temporary_file
Jander
la source
2
Vous pouvez forcer Firefox à ouvrir un nouveau processus avec -new-instance, il devient donc ... | firefox -new-instance /dev/fd/0.
rampion
cela fonctionne très bien, merci! quelqu'un sait-il comment faire cela avec Chrome à la place?
Alexander Mills
33

Vous pouvez utiliser des URI de données , comme ceci:

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

&0est le descripteur de fichier pour stdin, il code donc stdin en base64, puis interpole cela dans l'URI de données.

La même astuce fonctionne également pour les autres navigateurs:

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 vous voulez, vous pouvez mettre la deuxième partie dans un script bash (je l'appellerai pipefox.sh):

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

Vous pouvez maintenant:

echo '<h1>hello, world</h1>' |pipefox.sh
Boule de neige
la source
1
totalement génial !, Comment diable avez-vous trouvé ça?. Vous pouvez améliorer pipefox.sh en renommant pipebrowser avec le contexte: $ 1 "data: text / html; base64, $ (base64 -w 0 <& 0)" permettant de choisir le navigateur à votre convenance
albfan
J'ai une question similaire ici si c'est la même différence, stackoverflow.com/questions/32303025/…
1,21 gigawatts
2
Cela ne fonctionne malheureusement plus, consultez blog.mozilla.org/security/2017/11/27/… pour savoir pourquoi la plupart des types MIME dans les URL de données sont désormais bloqués de la navigation de haut niveau.
TheDiveO
7

J'ai trouvé ça:

bcat - utilitaire de redirection vers le navigateur

... pour installer sur Ubuntu Natty, j'ai fait:

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

Je pensais que cela fonctionne avec son propre navigateur - mais l'exécution de ce qui précède a ouvert un nouvel onglet dans un Firefox déjà en cours d'exécution, pointant vers une adresse localhost http://127.0.0.1:53718/btest... Avec l' bcatinstallation, vous pouvez également faire:

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

... un onglet s'ouvrira à nouveau, mais Firefox continuera d'afficher l'icône de chargement (et mettrait apparemment à jour la page lors de la mise à jour de syslog).

La bcatpage d'accueil fait également référence au navigateur uzbl , qui peut apparemment gérer stdin - mais pour ses propres commandes (devrait probablement examiner cela plus, cependant)


EDIT: Comme j'avais besoin de quelque chose comme ça (principalement pour afficher des tableaux HTML avec des données générées à la volée (et mon Firefox devient très lent à être utile avec bcat)), j'ai essayé avec une solution personnalisée. Depuis que j'utilise ReText , j'avais déjà installé python-qt4et les liaisons WebKit (et dépendances) sur mon Ubuntu. J'ai donc mis en place un script Python / PyQt4 / QWebKit - qui fonctionne comme bcat(pas comme btee), mais avec sa propre fenêtre de navigateur - appelé Qt4WebKit_singleinst_stdin.py(ou qwksisipour faire court):

Fondamentalement, avec le script téléchargé (et les dépendances), vous pouvez l'aliaser dans un bashterminal comme celui-ci:

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

... et dans un terminal (après alias), qwksisiouvrira la fenêtre principale du navigateur; tandis que dans un autre terminal (à nouveau après l'alias), on pourrait faire ce qui suit pour obtenir des données stdin:

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

... comme indiqué ci-dessous:

qwksisi

N'oubliez pas la -fin pour faire référence à stdin; sinon, un nom de fichier local peut également être utilisé comme dernier argument.

Fondamentalement, le problème ici est de résoudre:

  • problème d'instance unique (donc la première exécution du script devient un "maître" et ouvre une fenêtre de navigateur - tandis que les exécutions suivantes transmettent simplement les données au maître et quittent)
  • communication interprocessus pour partager des variables (afin que les processus sortants puissent transmettre des données à la fenêtre principale du navigateur)
  • Mise à jour du minuteur dans le maître qui vérifie le nouveau contenu et met à jour la fenêtre du navigateur si un nouveau contenu est arrivé.

En tant que tel, la même chose pourrait être implémentée dans, disons, Perl avec des liaisons Gtk et WebKit (ou un autre composant de navigateur). Je me demande, cependant, si le cadre XUL de Mozilla pourrait être utilisé pour implémenter la même fonctionnalité - je suppose que dans ce cas, on pourrait travailler avec le composant navigateur Firefox.

sdaau
la source
6

Vous pouvez utiliser la substitution de processus :

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

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

 firefox  <( echo "<h1>Hello number "{1..23}"!</h1>" )
rozcietrzewiacz
la source
1
Impossible de les faire fonctionner avec Ubuntu 14.04 en utilisant bash et Firefox 29.0
John S Gruber
5

Regardez ce que la recherche de «navigateur stdin» s'est avérée! , un joli petit script 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 vous l'enregistrez dans stdin2www, rendez-le exécutable ( chmod +x stdin2www), vos exemples devraient fonctionner via cat index.html | ./stdin2www. Notez simplement que les liens , images, etc. relatifs échoueront car la page qui sera ouverte est quelque chose /tmp/; plus de travail serait nécessaire pour résoudre ce problème.

sr_
la source
3

J'ai écrit un script python pour écrire stdin dans un fichier temporaire, puis ouvrir le fichier temporaire avec 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()
À M
la source
0

Vous pouvez exécuter la commande ci-dessous à partir d'une fenêtre de script / terminal shell.

Avant de lancer Firefox (ou tout autre navigateur), il lira depuis son contenu le contenu à afficher à l'ouverture.

Si ce n'est pas du HTML qui est envoyé, remplacez la text/htmlchaîne de l'URL ci-dessous par le type de fichier (par exemple, text/plainou image/png).

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

Un ffpipealias simple .

Les solutions URI de données fournies par snowball et luk3yx ne fonctionnent pas pour moi sur GNU / Linux.

L'alias suivant devrait fonctionner:

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

par exemple.

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

Limites

La page ne se chargera qu'une fois le tube fermé (c'est-à-dire que la fin du fichier a été atteinte).

Si le rendu incrémentiel du contenu redirigé est requis, il vaut mieux utiliser quelque chose comme l' bcatutilitaire mentionné précédemment .

pyrocrastie
la source
0

Bien que cette question ait sept ans, je suis surpris que personne ne propose une solution servant le fichier via un serveur Web. Ceci est réalisé avec le script Python3 compact suivant. Enregistrez-le en tant que fichier exécutable, par exemple, 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()

Ensuite, vous pouvez rediriger l'entrée standard vers le navigateur par défaut:

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

Par défaut, le serveur fonctionne sur le port 8000, mais ce comportement peut être modifié avec un argument de ligne de commande:

./browser.py 9000 < website.html

J'ai testé ce script sur Linux. Il devrait gérer les autres systèmes UNIX, y compris MacOS, prêts à l'emploi. Il est en principe même préparé pour Windows (je n'en ai pas pour les tests), mais il peut être nécessaire d'implémenter la fonctionnalité de délai différemment.

tglas
la source