Tengo un programa que almacena su configuración en ~/.config/myprogram
que uso tanto interactivamente como con un sistema de colas por lotes. Cuando se ejecuta de forma interactiva, quiero que este programa use mis archivos de configuración (y lo hace). Pero cuando se ejecuta en modo por lotes, los archivos de configuración no son necesarios porque especifico las opciones de línea de comandos que sobrescriben todas las configuraciones relevantes. Además, acceder a los archivos de configuración a través de la red aumenta el tiempo de inicio del programa en varios segundos; Si los archivos no existen, el programa se inicia mucho más rápido (ya que cada trabajo solo toma aproximadamente un minuto, esto tiene un impacto significativo en el rendimiento del trabajo por lotes). Pero debido a que también uso el programa de manera interactiva, no quiero mover / eliminar mis archivos de configuración todo el tiempo. Dependiendo de cuándo se programan mis trabajos por lotes en el clúster (según el uso de otros usuarios),
(Aparte: el rendimiento del archivo de red es tan lento que probablemente sea un error, pero solo soy un usuario del clúster, por lo que solo puedo solucionarlo, no solucionarlo).
Podría construir una versión del programa que no lea los archivos de configuración (o que no tenga una opción de línea de comandos) para el uso por lotes, pero el entorno de compilación de este programa está mal diseñado y es difícil de configurar. Preferiría usar los binarios instalados a través del administrador de paquetes de mi sistema.
¿Cómo puedo engañar a instancias particulares de este programa para fingir que mis archivos de configuración no existen (sin modificar el programa)? Espero un contenedor del formulario pretendfiledoesntexist ~/.config/myprogram -- myprogram --various-options...
, pero estoy abierto a otras soluciones.
LD_PRELOAD
gancho. Eso es más fácil (puede implementar eso en una hora o dos, si conoce C) que la alternativa, que esptrace
. Probablemente también podría usar fakechroot para hacer esto (que es LD_PRELOAD, creo).Respuestas:
Ese programa probablemente resuelve la ruta a ese archivo desde
$HOME/.config/myprogram
. Entonces podría decir que su directorio de inicio está en otro lugar, como:Ahora, tal vez su programa necesita algún otro recurso en su directorio de inicio. Si sabe cuáles son, puede preparar una casa falsa para su programa con enlaces al recurso que necesita allí.
fuente
Si todo lo demás falla, escriba una biblioteca de contenedor que inyectará
LD_PRELOAD
para que la llamada aopen("/home/you/my-program/config.interactive")
sea interceptada pero cualquier otra pase. Esto funciona para cualquier tipo de programa, incluso scripts de shell, ya que filtrará las llamadas al sistema.Nota: No he probado este código y no estoy 100% seguro de que la
errno
pieza funcione.Mira cómo
fakeroot
funciona para llamadas comogetuid(2)
ystat(2)
.Básicamente, el vinculador vinculará esa aplicación a su biblioteca, que anula el
open
símbolo. Como no puede usar dos funciones diferentes nombradasopen
en su propia biblioteca, debe separarla en una segunda parte (por ejemploget_real_open
) que a su vez se vinculará con laopen
llamada original .Original:
./Application
Interceptado:
LD_PRELOAD=yourlib_wrap.so ./Application
Editar: Aparentemente hay una
ld
bandera que puede habilitar (--wrap <symbol>
) que le permite escribir envoltorios sin tener que recurrir a enlaces dobles:fuente
Mueva su archivo de configuración fuera del camino y escriba un contenedor de script de shell para el caso de uso interactivo que copie el archivo en su destino normal, ejecute el programa y lo elimine al salir.
fuente
Esto debería ser posible con unionfs / aufs. Creas un
chroot
entorno para el proceso. Utiliza el directorio real como capa de solo lectura y coloca uno vacío encima. Luego, monta el volumen unionfs en el directorio respectivo delchroot
entorno y elimina el archivo allí. El proceso no lo verá, pero todos los demás sí.fuente
Cambie el nombre del archivo de configuración por ej
config.interactive
. Cree otro archivo vacío llamado egconfig.script
.Ahora, cree un enlace suave llamado
config
(o lo que la aplicación espere como un archivo de configuración) a la configuración real que necesite y ejecute su aplicación.Recuerde ordenar su enlace después.
fuente
Si ha caracterizado con precisión cómo su programa utiliza el archivo de configuración, lo he pasado por alto. Muchos programas (como
bash
yvi
) buscarán un archivo de configuración inmediatamente después del inicio; si el archivo existe, léalo y ciérrelo. Estos programas nunca vuelven a acceder a estos archivos de inicialización. Si su programa es así, siga leyendo.Sé que ha rechazado las respuestas que hacen que el archivo de configuración sea realmente inexistente (al renombrarlo), pero tengo una arruga que no he visto propuesta por nadie más. Haga esto cuando invoque el programa en modo por lotes:
Esto mueve el archivo de configuración fuera del camino, pero luego lo mueve un segundo más tarde, incluso si
myprogram
todavía se está ejecutando. Esto crea una ventana de tiempo muy breve durante la cual el archivo no está disponible. ¿Cuál es la probabilidad de que ejecute el programa de forma interactiva durante esta ventana? (Incluso si lo hace, puede salir y reiniciar, y el archivo de configuración probablemente volverá a su lugar).Esto crea una condición de carrera; Si el programa tarda demasiado en abrir el archivo, podría obtener el archivo real. Si esto sucede con la frecuencia suficiente como para que sea un problema, solo aumente el valor de DELAY_TIME.
fuente
Me gusta la respuesta de Stéphane, pero esto va a engañar a cualquier programa en la creencia de cualquier archivo está vacío - (debido a que su dentry apunta a un archivo temporal que realmente está vacío) :
También podrías:
Si querías.
fuente
mv
el archivo, lo que podría tener otras consecuencias que afectar su negación, como truncar el archivo u otros, etc., mientras que esto funciona en nada más que. Aún así, supongounshare
que deberíamount
...