como fazer com que o firefox leia stdin


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

Esses comandos não funcionam.
Se o firefox pode ler stdin, posso enviar html para o firefox via pipe.
É possível fazer o firefox ler stdin?


2
O que exatamente você quer realizar?
Pbm

6
@pbm: Pode ser útil para evitar o armazenamento de dados temporários ...
l0b0

Respostas:


23

A resposta curta é: é melhor escrever um arquivo temporário e abri-lo. Conseguir que os tubos funcionem corretamente é mais complicado e provavelmente não lhe dará nenhuma vantagem extra. Dito isto, aqui está o que eu encontrei.

Se seu firefoxcomando está realmente iniciando o Firefox em vez de falar com uma instância do Firefox já em execução, você pode fazer o seguinte:

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

O que instrui o Firefox a ler explicitamente sua entrada padrão, que é onde o canal está colocando seus dados. Mas se o Firefox já estiver em execução, o firefoxcomando apenas passará esse nome para o processo principal do Firefox, que lerá sua própria entrada padrão, o que provavelmente não fornecerá nada e certamente não está conectado ao seu pipe.

Além disso, ao ler de um canal, o Firefox armazena em buffer as coisas com bastante intensidade, de modo que não atualizará a página toda vez que você fornecer uma nova linha de HTML, se é isso que você deseja. Tente fechar o Firefox e execute:

cat | firefox /dev/fd/0

(NB, você realmente precisa do cataqui.) Cole algumas linhas longas na janela do shell repetidamente até o Firefox decidir atualizar a página e você poderá ver a quantidade de dados necessários. Agora envie um sinal de fim de arquivo pressionando Ctrl+Duma nova linha e assista ao Firefox atualizar instantaneamente. Mas não é possível adicionar mais dados.

Então, o melhor é provavelmente:

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

2
Você pode forçar o firefox a abrir um novo processo -new-instance, para que ele se torne ... | firefox -new-instance /dev/fd/0.
Rampion

isso funciona muito bem, obrigado! alguém sabe como fazer isso com o Chrome?
Alexander Mills

33

Você pode usar URIs de dados , assim:

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

&0é o descritor de arquivo para stdin, então ele codifica stdin para base64e interpola isso no URI de dados.

O mesmo truque também funciona para outros 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)"

Se você quiser, pode colocar a segunda parte em um script bash (eu vou chamá-lo pipefox.sh):

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

Agora você pode fazer:

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

1
totalmente incrível !, Como diabos você veio com isso ?. Você pode melhorar pipefox.sh renomeando para pipebrowser com o contexto: $ 1 "dados: text / html; base64, $ (base64 -w 0 <& 0)", permitindo escolher o navegador ao seu gosto
albfan

Eu tenho uma pergunta semelhante aqui, se é a mesma diferença, stackoverflow.com/questions/32303025/…
1,21 gigawatts

2
Infelizmente, isso não funciona mais, consulte blog.mozilla.org/security/2017/11/27/… para saber por que a maioria dos tipos mimetizados em URLs de dados agora é bloqueada na navegação de nível superior.
TheDiveO 23/07

7

Eu achei isto:

bcat - utilitário pipe para navegador

... para instalar no Ubuntu Natty, eu fiz:

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

Eu pensei que ele trabalha com seu próprio navegador - mas executar o acima abriu uma nova guia em um Firefox já em execução, apontando para um endereço de host local http://127.0.0.1:53718/btest... Com a bcatinstalação, você também pode:

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

... uma guia será aberta novamente, mas o Firefox continuará mostrando o ícone de carregamento (e aparentemente atualizaria a página quando o syslog for atualizado).

A bcatpágina inicial também faz referência ao navegador uzbl , que aparentemente pode lidar com o stdin - mas por seus próprios comandos (provavelmente deveria olhar mais para isso)


Edição: Como eu precisava muito de algo assim (principalmente para visualizar tabelas HTML com dados gerados em tempo real (e meu Firefox está ficando muito lento para ser útil bcat)), tentei com uma solução personalizada. Desde que eu uso o ReText , eu já tinha python-qt4ligações instaladas e WebKit (e dependências) no meu Ubuntu.Então, montei um script Python / PyQt4 / QWebKit - que funciona como bcat(não como btee), mas com sua própria janela do navegador - chamada Qt4WebKit_singleinst_stdin.py(ou qwksisiabreviada):

Basicamente, com o script baixado (e dependências), você pode alterná-lo em um bashterminal como este:

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

... e em um terminal (após o aliasing), qwksisiaumentará a janela principal do navegador; enquanto em outro terminal (novamente após o alias), pode-se fazer o seguinte para obter dados stdin:

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

... como mostrado abaixo:

qwksisi

Não esqueça o -no final para se referir a stdin; caso contrário, um nome de arquivo local também poderá ser usado como último argumento.

Basicamente, o problema aqui é resolver:

  • problema de instância única (portanto, a primeira execução do script se torna um "mestre" e abre uma janela do navegador - enquanto as execuções subsequentes simplesmente passam os dados para o mestre e a saída)
  • comunicação entre processos para compartilhar variáveis ​​(para que os processos de saída possam passar dados para a janela principal do navegador)
  • Atualização do cronômetro no mestre que verifica se há novo conteúdo e atualiza a janela do navegador se chegar novo conteúdo.

Como tal, o mesmo poderia ser implementado no, digamos, Perl com ligações Gtk e WebKit (ou outro componente do navegador). Eu me pergunto, no entanto, se o framework XUL da Mozilla poderia ser usado para implementar a mesma funcionalidade - acho que, nesse caso, alguém funcionaria com o componente do navegador Firefox.


6

Você pode usar a substituição de processo :

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

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

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

1
Não é possível obter estes para o trabalho com o Ubuntu 14.04 usando bash e Firefox 29.0
John S Gruber

5

Veja o que a pesquisa por 'browser stdin' apareceu! , um pequeno e agradável 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

Se você salvar isso stdin2www, torne-o executável ( chmod +x stdin2www), seus exemplos deverão funcionar cat index.html | ./stdin2www. Apenas observe que links , imagens, etc. relativos falharão, pois a página que será aberta é algo /tmp/; seria necessário mais trabalho para corrigir isso.


3

Eu escrevi um script python para gravar stdin em um arquivo temporário e depois abrir o arquivo temporário com o 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

Você pode executar o comando abaixo em uma janela de script / terminal do shell.

Antes de iniciar o Firefox (ou qualquer outro navegador), ele lerá o conteúdo exibido na abertura.

Se não for enviado HTML, altere a text/htmlsequência no URL abaixo para qualquer que seja o tipo de arquivo (por exemplo, text/plainou image/png).

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

0

Um ffpipealias simples .

As soluções URI de dados fornecidas pelo snowball e pelo luk3yx não estão funcionando para mim no GNU / Linux.

O seguinte alias deve funcionar:

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

por exemplo.

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

Limitações

A página será carregada apenas quando o tubo estiver fechado (ou seja, o fim do arquivo foi atingido).

Se a renderização incremental do conteúdo canalizado for necessária, é melhor usar algo como o bcatutilitário mencionado anteriormente .


0

Embora essa pergunta tenha sete anos, estou surpreso que ninguém tenha proposto uma solução para servir o arquivo através de um servidor web. Isso é obtido com o seguinte script Python3 compacto. Salve-o como um arquivo executável, por exemplo, 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()

Em seguida, você pode redirecionar a entrada padrão para o navegador padrão:

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

Por padrão, o servidor opera na porta 8000, mas esse comportamento pode ser alterado com um argumento de linha de comando:

./browser.py 9000 < website.html

Eu testei esse script no Linux. Ele deve lidar com outros sistemas UNIX, incluindo o MacOS imediatamente. Em princípio, ele está preparado para o Windows (não tenho um para teste), mas pode ser necessário implementar a funcionalidade de tempo limite de maneira diferente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.