Como posso criar um arquivo especial que executa código quando lido de [duplicado]?

7

A maioria dos arquivos em um sistema Linux são arquivos normais, ou seja, eles são salvos em disco e a leitura deles é feita a partir de um pedaço especificado de memória no disco. Como posso fazer algo que se comporta como um arquivo em termos de ser capaz de ler a partir dele como se fosse um arquivo normal, mas na verdade retornando dados gerados programaticamente? Como um exemplo concreto, um arquivo que baixa o google.com atual e o retorna, de modo que cat ~/myspecialfile produziria o conteúdo de google.com para stdout?

    
por Christopher Shroba 19.09.2014 / 22:07

3 respostas

8

Como as outras respostas indicaram, você pode fazer parte do que solicitou usando pipes nomeados. Para uma solução completa, você teria que desenvolver algum tipo de sistema de arquivos virtual que tomou as ações desejadas quando um caminho no sistema de arquivos virtual foi acessado. Existem algumas abordagens para fazer isso:

  • Escreva um driver do sistema de arquivos do modo kernel, como o driver procfs .
  • Escreva uma implementação do sistema de arquivos do modo de usuário, usando o FUSE , por exemplo.
  • Escreva um programa que forneça uma interface Servidor NFS ou outro protocolo de sistema de arquivos de rede.
  • Talvez um programa que finge ser um dispositivo de armazenamento de arquivos USB ou outra peça de hardware.
por 19.09.2014 / 22:50
7

Você pode fazer algo assim com um FIFO / named pipe:

$ mkfifo ~/myspecialfile
$ wget -q -O ~/myspecialfile google.com &
[2] 26186
$ 

mkfifo cria um pipe nomeado chamado ~ / myspecialfile. wget , em seguida, direciona sua saída para esse pipe nomeado. Você pode ler (uma vez) desse pipe nomeado como se fosse um arquivo regular. por exemplo. para obter wc contagens para esse arquivo:

$ wc ~/myspecialfile
      7     430   17738 /home/ubuntu/myspecialfile
[2]+  Done                    wget -q -O ~/myspecialfile google.com
$ 

Observe que normalmente o gravador ( wget nesta instância) irá open() do canal com o sinalizador O_WRONLY. Essa chamada open() normalmente bloqueará até que o leitor ( wc neste exemplo) abra a outra extremidade do canal com o sinalizador O_RDONLY. Então aqui o processo wget será iniciado imediatamente, mas não estará fazendo nada em segundo plano até que o leitor (abre e) comece a ler. Eu verifiquei este comportamento com wireshark no Ubuntu 14.04.

    
por 19.09.2014 / 22:27
4

Você pode tornar myspecialfile um pipe nomeado. Então você pode ter um script rodando em segundo plano em um loop escrevendo a saída do programa para o pipe:

#!/bin/bash
mkfifo ~/myspecialfile
while :; do
    run program here > ~/myspecialfile
done

Há uma limitação para isso. Se dois processos abrirem o arquivo ao mesmo tempo, cada um deles obterá apenas partes da saída.

Uma maneira mais elaborada de fazer algo que não tem essa limitação seria implementar um sistema de arquivos FUSE. ~/myfyspecialfile seria o ponto de montagem do sistema de arquivos.

    
por 19.09.2014 / 22:24