Eu tenho um programa que armazena suas configurações em ~/.config/myprogram
que eu uso interativamente e com um sistema de enfileiramento em lote. Ao executar interativamente, desejo que este programa use meus arquivos de configuração (e é o que faz). Mas, quando executados no modo em lote, os arquivos de configuração não são necessários porque eu especifico opções de linha de comando que substituem todas as configurações relevantes. Além disso, o acesso aos arquivos de configuração pela rede aumenta o tempo de inicialização do programa em vários segundos; se os arquivos não existirem, o programa será iniciado muito mais rapidamente (como cada trabalho leva apenas cerca de um minuto, isso tem um impacto significativo no rendimento do trabalho em lotes). Mas como também uso o programa interativamente, não quero mover / excluir meus arquivos de configuração o tempo todo. Dependendo de quando meus trabalhos em lotes são agendados no cluster (com base no uso de outros usuários),
(Além disso: o desempenho do arquivo de rede é tão lento provavelmente é um bug, mas eu sou apenas um usuário do cluster, então só posso contorná-lo, não corrigi-lo.)
Eu poderia criar uma versão do programa que não lê os arquivos de configuração (ou não tem uma opção de linha de comando) para uso em lote, mas o ambiente de compilação desse programa é mal projetado e difícil de configurar. Eu preferiria usar os binários instalados através do gerenciador de pacotes do meu sistema.
Como enganar instâncias específicas deste programa para fingir que meus arquivos de configuração não existem (sem modificar o programa)? Espero um invólucro do formulário pretendfiledoesntexist ~/.config/myprogram -- myprogram --various-options...
, mas estou aberto a outras soluções.
LD_PRELOAD
gancho. Isso é mais fácil (você pode implementar isso em uma hora ou duas, se souber C) do que a alternativa, que éptrace
. Você provavelmente também poderia usar o fakechroot para fazer isso (que é LD_PRELOAD, acredito).Respostas:
Esse programa provavelmente resolve o caminho para esse arquivo
$HOME/.config/myprogram
. Então você pode dizer que seu diretório pessoal está em outro lugar, como:Agora, talvez o seu programa precise de algum outro recurso no seu diretório pessoal. Se você souber quais são, poderá preparar uma casa falsa para o seu programa, com links para os recursos necessários.
fonte
Se tudo mais falhar, escreva uma biblioteca de wrapper que você injetará
LD_PRELOAD
para que a chamadaopen("/home/you/my-program/config.interactive")
seja interceptada, mas qualquer outra seja transmitida. Isso funciona para qualquer tipo de programa, mesmo shell scripts, pois filtrará as chamadas do sistema.Nota: Eu não testei esse código e não tenho 100% de certeza de que a
errno
peça funcione.Veja como o
fakeroot
faz para chamadas comogetuid(2)
estat(2)
.Basicamente, o vinculador vincula esse aplicativo à sua biblioteca, que substitui o
open
símbolo. Como você não pode usar duas funções diferentes nomeadasopen
em sua própria biblioteca, é necessário separá-la em uma segunda parte (por exemploget_real_open
) que, por sua vez, será vinculada àopen
chamada original .Original:
./Application
Interceptado:
LD_PRELOAD=yourlib_wrap.so ./Application
Edit: Aparentemente, existe um
ld
sinalizador que você pode ativar (--wrap <symbol>
) que permite escrever wrappers sem ter que recorrer à vinculação dupla:fonte
Mova seu arquivo de configuração para fora do caminho e escreva um wrapper de script de shell para o caso de uso interativo que copia o arquivo para seu destino normal, executa o programa e o exclui na saída.
fonte
Isso deve ser possível com o unionfs / aufs. Você cria um
chroot
ambiente para o processo. Você usa o diretório real como camada somente leitura e coloca um vazio em cima dele. Em seguida, você monta o volume unionfs no diretório respectivo nochroot
ambiente e exclui o arquivo lá. O processo não o verá, mas todos os outros o fazem.fonte
Renomeie o arquivo de configuração para, por exemplo
config.interactive
. Crie outro arquivo vazio chamado por exemploconfig.script
.Agora, crie um link virtual chamado
config
(ou o que o aplicativo espera como um arquivo de configuração) para a configuração real necessária e execute seu aplicativo.Lembre-se de arrumar seu link posteriormente.
fonte
Se você caracterizou precisamente como seu programa usa o arquivo de configuração, eu o ignorei. Muitos programas (como
bash
evi
) verificarão um arquivo de configuração imediatamente após o início; se o arquivo existir, leia-o e feche-o. Esses programas nunca acessam esses arquivos de inicialização novamente. Se o seu programa for assim, continue lendo.Sei que você rejeitou respostas que tornam o arquivo de configuração realmente inexistente (renomeando-o), mas tenho uma ruga que ainda não vi proposta por mais ninguém. Faça isso quando você chamar o programa no modo em lote:
Isso move o arquivo de configuração para fora do caminho, mas o move um segundo depois, mesmo se
myprogram
ainda estiver em execução. Isso cria uma janela muito breve durante o qual o arquivo não está disponível - qual é a probabilidade de você executar o programa interativamente durante essa janela? (Mesmo que você faça isso, você pode simplesmente sair e reiniciar, e o arquivo de configuração provavelmente estará de volta no lugar.)Isso cria uma condição de corrida; se o programa demorar muito para abrir o arquivo, ele poderá obter o arquivo real. Se isso acontecer com frequência suficiente, é um problema, apenas aumente o valor de DELAY_TIME.
fonte
I como a resposta de Stephane, mas isso vai enganar qualquer programa em acreditar qualquer arquivo está vazio - (porque a sua dentry temporariamente aponta para um arquivo que realmente está vazia) :
Você também pode:
Se você quisesse.
fonte
mv
arquivo - que pode ter outras conseqüências além de afetar seu dentry, como na verdade truncar o arquivo ou outros e etc. - enquanto isso funciona apenas com. Ainda assim, devounshare
quemount
eu acho ...