É possível criar conteúdo dinâmico na operação de leitura de arquivos?

3

É possível gerar conteúdo de arquivo com base no nome do arquivo?

Eu preciso de muitos arquivos .conf semelhantes com conteúdo, dependendo apenas do nome do arquivo.

Posso criar um arquivo "dinâmico" e gerar vários links simbólicos apontando para esse arquivo?

Talvez o fifo seja uma solução, mas não consigo colocar o nome do arquivo na geração do script:

zsh$ mkfifo ./dynamic.conf
zsh$ ln -s ./dynamic.conf ./case1.conf
zsh$ echo $0  > ./dynamic.conf & 
zsh$ cat ./case1.conf

Eu tenho zsh (preciso de case1.conf ).

    
por kakabomba 09.05.2015 / 16:19

3 respostas

1

Abordagem totalmente diferente porque só sei que seus olhos estão rolando na última resposta.

Neste, você vai confiar em inotify , o que significa que é realmente específico para Linux. Você vai virar o problema de cabeça para baixo - os arquivos de configuração individuais ainda estarão lá, mas você irá gerá-los novamente automaticamente cada vez que houver uma mudança no master .

Você tem o seu arquivo de configuração "mestre", digamos master.conf , que contém todas as suas seções, subseções, etc. Você configura seu script com inotify para que quando esse script for alterado, ele escreva todos esses arquivos. (Para evitar uma condição de corrida, você pode ter que fazer alguns truques extras, como armazenar os arquivos em um subdiretório e trocar os diretórios para executar seu "commit").

A partir do link , obtemos um script básico em perl:

my $inotify = Linux::Inotify2->new;
$inotify->watch("/etc/master.conf", IN_MODIFY);
while () {
  my @events = $inotify->read;
  unless (@events > 0){
    print "read error: $!";
    last ;
  }

  foreach my $event (@events) {
    next unless $event->IN_MODIFY;
    # 1. TODO: RE-READ IN THE CONFIG FILE
    # (example)
    $config_hash = &parse_master_file;

    # 2. TODO: RE-GENERATE YOUR CONFIG FILES
    # (example)
    for $section qw( section1 section2 misc ) {
        open(S,"> /etc/${section}.conf")
        print S &dump_config($config_hash,$section)
        close(S)
    }
  }
}

Fazer o parse_master_file e dump_config dependerá de você. Além disso, provavelmente deve haver uma chamada para dormir no loop principal ou sua CPU vai pegar fogo.

    
por 10.05.2015 / 05:52
1

Você tem um aplicativo / programa que lê todos esses .conf arquivos e quer consolidá-los todos em um arquivo que dinamicamente cria as informações apropriadas para o nome do arquivo escolhido pelo programa. O problema com a solução baseada em pipe é que o programa que alimenta o pipe não pode detectar o arquivo que o consumidor abriu ou deseja ler. Então você precisa de outro método.

Uma solução pouco conhecida para um problema frustrante de outro domínio: ao criar rpms, precisamos cortar o processo de rpmbuild para corrigir algum problema menor com a etapa final de empacotamento. O arquivo spec tem várias "seções" pertinentes ao RPM que estamos construindo ... preparar, construir, arquivos. Quando nosso programa é compilado, mas há algum erro na seção de arquivos, queremos que o rpmbuild pule a recompilação. Mas não vai fazer isso .... por design.

Um cara descobre que você pode usar LD_PRELOAD para carregar um arquivo so / dll especialmente projetado que captura a chamada open . Se a chamada open for para um arquivo de especificação, ela fornecerá entradas nulas para todas, exceto a seção files , para que quando rpmbuild estiver lendo o arquivo, ele esteja realmente lendo o que esta DLL está informando.

Eu usei isso por muitas semanas, mas em algum momento, eu limpei a VM, removendo esse programa da existência e desde então não consegui encontrá-lo. :( Um programa chamado mock faz isso agora, mas não tenho idéia se ele faz da mesma maneira ou usa outra abordagem.

Mas essa é a ideia. Você precisa encontrar uma DLL que possa ser carregada via LD_PRELOAD e substituir a chamada open para aquele programa, mas repassar a chamada (para a real) para arquivos nos quais você não está interessado. Para aqueles que você está interessado, alimenta os dados encontrados e consolidados pelo seu arquivo principal.

Som complicado? Sim, um pouco. No lado positivo, você terá as ferramentas para criar alguns root-kits e trojans realmente desagradáveis.

Para verificar se isso pode funcionar, execute o programa usando ltrace -e open <program> da seguinte forma:

ltrace -e open /usr/bin/tail /etc/fstab

Você verá essa saída (semelhante) ...

(0, 0, 0, 0x7f1c32ade000, 88)                             = 0x3055621160
open("/etc/fstab", 0, 00)                             = 4

Contanto que seu programa esteja usando o glibc para abrir esses arquivos (e não, digamos, uma chamada direta ao sistema), você o verá na saída acima e estará no negócio.

O próximo passo: um cara descreve em detalhes como substituir a chamada ioctl . Isso vai colocá-lo no caminho certo. Um tutorial muito bom aqui

    
por 10.05.2015 / 02:45
0

As soluções apresentadas são muito loucas para uso em produção.

Do fato de você parecer bem com a abordagem inotify (os arquivos são explicitamente regenerados após a modificação do mestre conf), segue-se que você pode simplesmente ter um script simples que regenere todo o seu lixo. Lá, inotify evitado sem perda de funcionalidade. A vantagem é que você tem menos coisas para depurar e não precisa tomar conta do processo em segundo plano.

Para o lulz, deve-se notar que a funcionalidade em questão pode ser alcançada, mas não consigo ver qualquer razão para fazê-lo. Aqui vai: um sistema de arquivos especial (por exemplo, baseado em fusível) e voila - open, read etc. rotinas emitidas por qualquer um que lide com esses arquivos acabam chamando seu código, assim você pode enviar qualquer conteúdo que você queira. Mas, novamente, por que você faria isso?

    
por 11.05.2015 / 09:31