Limpar maneira de substituir temporariamente um arquivo de configuração?

7

Eu uso um programa de desenho chamado Inkscape, que tem uma interface gráfica e de linha de comando. Quando usado na linha de comando, ele tem um grande número de opções que só podem ser controladas por meio de um arquivo de configuração específico do usuário, que é codificado para ser:

$HOME/.config/inkscape/preferences.xml

Este arquivo de configuração sempre contém as opções usadas mais recentemente na GUI, que podem ser as mais incorretas quando estou fazendo scripts.

Para contornar isso, eu tenho meu script salvar uma cópia do arquivo de configuração, substituí-lo por um arquivo de configuração padrão, executar o programa e, em seguida, copiar o arquivo de configuração salvo de volta.

Isso funciona bem, mas não é realmente limpo. Por exemplo, ele não funcionará corretamente se duas instâncias do script estiverem sendo executadas simultaneamente.

No Unix, existe uma maneira mais limpa de executar essa tarefa de falsificar um programa, de modo que ele pegue seu arquivo de configuração de algum lugar que eu queira, em vez de partir do nome de caminho codificado no programa? Talvez algo envolvendo links, ou algo como as cadeias de BSD?

    
por Ben Crowell 02.11.2013 / 03:40

4 respostas

9

O Inkscape tem um recurso para este a partir de 0,47 :

$ INKSCAPE_PORTABLE_PROFILE_DIR=/some/other/path inkscape --args

Coloque o arquivo preferences.xml personalizado do seu script em /some/other/path . Deve ser um diretório dedicado, porque o Inkscape irá preenchê-lo com todos os outros arquivos que normalmente coloca em ~/.config/Inkscape quando você o executa assim.

    
por 02.11.2013 / 05:02
7

Como o Inkscape é o software FOSS , podemos adicionar uma opção ao programa que permitirá que você passe o nome de outro arquivo de configuração, assim:

=== modified file 'src/inkscape.cpp'
--- src/inkscape.cpp    2013-09-28 19:20:27 +0000
+++ src/inkscape.cpp    2013-11-02 04:07:45 +0000
@@ -1443,6 +1443,12 @@
             prefdir = g_strdup(val);
         }

+        // Also accept an override via the command line
+        extern gchar* sp_preferences;
+        if (sp_preferences) {
+            prefdir = sp_preferences;
+        }
+
 #ifdef HAS_SHGetSpecialFolderLocation
         // prefer c:\Documents and Settings\UserName\Application Data\ to
         // c:\Documents and Settings\userName\;

=== modified file 'src/main.cpp'
--- src/main.cpp    2013-09-24 18:31:44 +0000
+++ src/main.cpp    2013-11-02 04:05:30 +0000
@@ -179,6 +179,7 @@
     SP_ARG_VERB_LIST,
     SP_ARG_VERB,
     SP_ARG_SELECT,
+    SP_ARG_PREFERENCES,
     SP_ARG_LAST
 };

@@ -228,6 +229,7 @@
 static gboolean sp_query_all = FALSE;
 static gchar *sp_query_id = NULL;
 static gboolean sp_shell = FALSE;
+gchar *sp_preferences = NULL;
 static gboolean sp_vacuum_defs = FALSE;
 #ifdef WITH_DBUS
 static gboolean sp_dbus_listen = FALSE;
@@ -520,6 +522,11 @@
      N_("Start Inkscape in interactive shell mode."),
      NULL},

+    {"preferences", 0,
+     POPT_ARG_STRING, &sp_preferences, SP_ARG_PREFERENCES,
+     N_("Specify a different preferences.xml file."),
+     NULL},
+
     POPT_AUTOHELP POPT_TABLEEND
 };

Eu não esperaria que os desenvolvedores do Inkscape aceitassem este patch, por dois motivos. Primeiro, eles têm um recurso alternativo com o mesmo efeito. Mas segundo, eu não esperaria que eles gostassem do modo como eu fiz sp_preferences global de programas em vez de global de módulos. Esse tipo de código é bom para um recurso pessoal que você não pretende fazer parte do software principal, no entanto.

O patch acima pode parecer bastante feio para um não-programador ou não familiarizado com C ++ e arquivos de patch , mas confie em mim, isso é tão simples quanto as mudanças no software. São apenas 10 linhas de código novo.

(Se você fizer a sua própria contagem e chegar a 13 novas linhas, três delas estão em branco ou têm apenas uma chave, então você não inclui as que estão no SLOC count.)

    
por 02.11.2013 / 04:13
1

Você pode usar links simbólicos. Coloque o arquivo de configuração que você usa com sua GUI em algum lugar, vamos chamá-lo GUI_CONFIG e aquele com scripts para SCRIPT_CONFIG. No início do seu script, coloque a linha:

ln -sf SCRIPT_CONFIG $HOME/.config/inkscape/preferences.xml

e no final:

ln -sf GUI_CONFIG $HOME/.config/inkscape/preferences.xml

Quando o script for executado, ele tornará preferences.xml um link simbólico que aponta para a configuração necessária. Quando terminar, ele aponta de volta para o que a GUI usa. A execução simultânea de vários scripts não destruirá sua configuração, como acontece ao copiar arquivos temporários, embora o primeiro script seja concluído irá quebrar o arquivo de configuração para os scripts em execução. Talvez seja melhor colocar as chamadas para ln em torno das chamadas individuais para o Inkscape, em vez dos scripts como um todo, para tentar evitar essas condições de corrida.

Outra opção seria executar o Inkscape como um usuário diferente dos scripts, para que você possa configurá-lo com um arquivo de configuração diferente. No entanto, você terá que lidar com as permissões, possivelmente copiando os arquivos para /tmp .

    
por 02.11.2013 / 04:16
1

Examinando a documentação do subsistema de preferências no Inkscape, não é possível.

Suas opções:

  1. faça o que você está fazendo
  2. jogue jogos vinculando o arquivo
  3. usuário com um ID de usuário diferente
  4. modifique a fonte (veja resposta do @ WarrenYoung para isso!)
por 02.11.2013 / 04:16