Crie um arquivo virtual que seja realmente um comando

18

Existe alguma maneira de criar um arquivo virtual, de modo que a leitura do arquivo realmente seja a partir stdoutde um comando; escrever no arquivo está gravando no stdincomando?

Até agora, classifiquei isso com um inotifywaitem um arquivo, que chama um comando quando o arquivo é modificado, pegando sua entrada do arquivo e escrevendo de volta para ele.

Eu não gosto que inotifywaitisso precise ser constantemente reiniciado (e eu tenho que garantir que ele esteja sempre em execução). Eu só uso esse arquivo talvez duas vezes por semana.

jsj
fonte

Respostas:

17

Você pode estar procurando um pipe nomeado .

mkfifo f
{
  echo 'V cebqhpr bhgchg.'
  sleep 2
  echo 'Urer vf zber bhgchg.'
} >f
rot13 < f

Escrever no canal não inicia o programa de audição. Se você deseja processar a entrada em um loop, é necessário manter um programa de escuta em execução.

while true; do rot13 <f >decoded-output-$(date +%s.%N); done

Observe que todos os dados gravados no canal são mesclados, mesmo se houver vários processos gravados. Se vários processos estiverem sendo lidos, apenas um obtém os dados. Portanto, um tubo pode não ser adequado para situações simultâneas.

Um soquete nomeado pode manipular conexões simultâneas, mas isso está além dos recursos para scripts shell básicos.

No final mais complexo da escala estão os sistemas de arquivos personalizados , que permite desenhar e montar um sistema de arquivos onde cada open, writeetc., desencadeia uma função em um programa. O investimento mínimo é de dezenas de linhas de codificação não trivial, por exemplo, em Python . Se você deseja executar apenas comandos ao ler arquivos, pode usar scriptfs ou fuseflt .

Gilles 'SO- parar de ser mau'
fonte
3

Algumas coisas a serem observadas em relação aos pipes nomeados: Um pipe não pode - ao contrário de um arquivo - ter vários leitores. Depois que o conteúdo é lido, ele desaparece. Então, você precisa fazer um loop, ou seja, você deve constantemente empurrar o conteúdo para dentro do canal do gravador.

Eu tenho procurado uma resposta para esta pergunta e a única outra coisa que consegui sugerir é o scriptfs, que é baseado no fusível .

unixhacker2010
fonte
1

O que você descreve é ​​essencialmente um arquivo especial FIFO, consulte fifo(7). Eles são criados por mkfifo(1)e um processo pode abri-los no Linux para R / W (nem todos os sistemas Unixy lidam com isso). Dois processos independentes podem então usá-lo para se comunicar.

vonbrand
fonte
0

A maneira mais fácil de "Criar um arquivo virtual que é realmente um comando" é estender o sistema de arquivos do FUSE. É muito fácil fazer isso com bibliotecas como o fusepy.

Aqui está um exemplo de um sistema de arquivos FUSE que permite ler arquivos HTTP / HTTPS / FTP como se estivessem presentes em sua própria caixa Linux. Da mesma forma, você pode criar algo que execute qualquer comando para o mesmo na leitura.

Se você olhar para o código - fonte , dificilmente haverá 50 linhas de código (excluindo qualquer código padrão).

supersan
fonte