ExecStart non é un shell: arranxar unha unidade auxiliar de VPN
ExecStart executa un programa con argumentos, non unha tubaxe de shell. Use un intérprete explícito ou un script real; despois verifique a unidade e lea o rexistro.
Copie unha liña de ordes que funcione en ExecStart, recargue e a unidade falla ou sae en silencio cos argumentos tratados como nomes de ficheiro. Nada está roto en systemd. ExecStart é unha lista de argumentos, non un shell, así que as tubaxes, a redirección e os condicionais perden o sentido no momento en que saen do seu terminal. Decida onde corresponde o shell e logo escriba unha unidade que diga exactamente que se debe executar.
Por que a tubaxe de ExecStart non fai nada
Cando se escribe unha orde nun terminal, o shell analízaa primeiro. Constrúe unha tubaxe, abre ficheiros para a redirección e expande variables antes de que comece calquera programa. systemd non fai nada diso: divide ExecStart segundo as súas propias regras e executa o programa resultante con eses argumentos. Por iso > chega como argumento literal, e | entrégase ao programa en lugar de conectar dous procesos. A unidade non se comporta mal; a sintaxe quería dicir outra cousa.
Iso é deliberado e non descoidado, porque o tratamento previsible dos argumentos é o que fai auditable as unidades. Só sorprende a quen dá por feito que hai un shell.
Escriba unha unidade que diga exactamente que se executa
Empece cunha unidade pequena cuxo propósito sexa visible no rexistro, para que os problemas de análise queden separados dos do túnel. Esta só informa da versión dun binario.
[Unit]
Description=Report the installed OpenVPN version
[Service]
Type=oneshot
ExecStart=/usr/sbin/openvpn --version
StandardOutput=journal
StandardError=journalA ruta é un marcador de posición, así que substitúao polo binario que realmente está instalado. Type=oneshot encaixa cunha orde que se executa ata rematar, e a configuración do rexistro pon a súa saída onde poida lela sen terminal. Deliberadamente non hai sección de instalación, así que a unidade invócase a man en lugar de habilitarse no arranque. Valide o ficheiro antes de inicialo, porque unha errata no nome dunha directiva falla de forma distinta que unha errata na ruta.
systemd-analyze verify /etc/systemd/system/openvpn-version.service
systemctl start openvpn-version.serviceManteña a lóxica de shell nun script
Cando un auxiliar necesita de verdade lóxica condicional, poña esa lóxica nun script e chámeo explicitamente. O script necesita unha liña de intérprete, permiso de execución e códigos de saída que o servizo poida informar. Lanzar /bin/sh -c cunha orde entre comiñas funciona, pero esconde as regras de comiñas dentro dunha unidade e dificulta a revisión. Un script con nome pódese probar a man e substituír despois sen editar a unidade. Non confíe no perfil de shell do usuario interactivo, porque un servizo arrinca co seu propio ambiente.
Estableza WorkingDirectory cando importan as rutas relativas, e pase o ambiente mediante as directivas admitidas da unidade en lugar de exportalo nun terminal. Os segredos pertencen a ficheiros protexidos ou credenciais, non a listas de argumentos que o rexistro poida gravar.
Comprobe a unidade que realmente existe
Os ficheiros drop-in cambian o comportamento sen tocar o ficheiro que recorda ter editado. Lea que cargou o xestor e que informou a última execución.
systemctl cat vpn-helper.service
journalctl -u vpn-helper.service -n 20 --no-pagerO volcado da unidade inclúe os drop-in en orde de carga, e de aí adoita vir un ExecStart inesperado. Tras calquera cambio, recargue o xestor e confirme que a nova definición é o que imprime systemctl cat. O rexistro mostra a liña de ordes exacta e o estado de saída, o que separa un problema de argumentos dun binario ausente ou dun erro de permisos. Despois decida se o auxiliar pertence ao ciclo de vida da VPN existente ou debe seguir sendo un diagnóstico manual, porque un segundo proceso de túnel en segundo plano crea un propietario en competencia.
Unha unidade que imprime a saída correcta cando se lle pide é un bo primeiro fito. Aínda non é un túnel, e non debería finxir que o é.