## Leer variables de entorno desde DKL DKL no tiene una función nativa para leer variables de entorno, pero se puede usar el método de .NET `System.Environment.GetEnvironmentVariable` con `_map_function`. Es útil, por ejemplo, para tomar parámetros de configuración del servidor sin escribirlos en el código. ### Las dos funciones que hacen falta Se mapea el mismo método **dos veces**, con distinto tipo de retorno: * Con `*` (referencia) se puede preguntar con `isnull()` si la variable existe, pero esa referencia no se puede asignar a una variable de cadena. * Con `$` (cadena) se obtiene el valor, pero si la variable no existe devuelve nulo, y al usarlo en una expresión (por ejemplo, al concatenarlo) se produce el error `Tipos no coinciden`. El tipo de retorno se indica con su código (`$`, `#`, `*`, `void`), no con el nombre del tipo de .NET: con `"System.String"` en esa posición se produce el error `Input string was not in a correct format`. La función `env.get` combina las dos y devuelve un valor predeterminado cuando la variable no existe: ```DKL #include "dkli.dkh" #! program "variables de entorno" { #include "functions.dkh" do _map_function(-1, "System.Environment", "GetEnvironmentVariable", "sys.getenv.ref", "System.String", "*") do _map_function(-1, "System.Environment", "GetEnvironmentVariable", "sys.getenv.str", "System.String", "$") env.get::nombre, predeterminado { if isnull(sys.getenv.ref(nombre)) { return predeterminado } return sys.getenv.str(nombre) } servidor = env.get("MIAPP_DB_HOST", "localhost") puerto = env.get("MIAPP_DB_PORT", "3306") do print("Servidor: " + servidor + ", puerto: " + puerto) } ``` Resultados: | Variables | Salida | |---|---| | Ninguna definida | `Servidor: localhost, puerto: 3306` | | `MIAPP_DB_HOST=db.ejemplo.local` y `MIAPP_DB_PORT` definida pero vacía | `Servidor: db.ejemplo.local, puerto: ` | Observe que una variable **definida pero vacía** devuelve `""`, no el valor predeterminado. Si va a usar `env.get` en varios programas, puede ponerla en un archivo de inclusión. Recuerde que un archivo incluido empieza en modo declarativo: debe iniciar con `#!` antes de `module` (vea [Errores frecuentes](../Referencia-del-lenguaje/errores-frecuentes.md)). ### Variables de entorno para el servicio FastCGI en Linux (systemd) Si el servicio FastCGI de Devkron se ejecuta como una unidad de systemd, las variables se le dan con un archivo *drop-in*, sin modificar la unidad original. En los ejemplos, la unidad se llama `devkron-fastcgi.service`; use el nombre de la suya. 1. Cree el directorio y el archivo del drop-in: ```bash sudo mkdir -p /etc/systemd/system/devkron-fastcgi.service.d sudo nano /etc/systemd/system/devkron-fastcgi.service.d/entorno.conf ``` 2. Escriba las variables de una de estas dos formas. Con `Environment=` directamente en el drop-in. **Entrecomille la asignación completa**: systemd separa por espacios, y `Environment=MIAPP_TITULO=Mi aplicación` solo asignaría `Mi`: ```ini [Service] Environment="MIAPP_DB_HOST=db.ejemplo.local" Environment="MIAPP_TITULO=Mi aplicación de ejemplo" ``` Con `EnvironmentFile=`, apuntando a un archivo aparte. Es la opción recomendada para valores que no deben quedar a la vista, porque ese archivo puede tener permisos restringidos (por ejemplo, `640`, dueño `root` y el grupo con el que corre el servicio): ```ini [Service] EnvironmentFile=/etc/devkron/miapp.env ``` Contenido de `/etc/devkron/miapp.env`: ```ini MIAPP_DB_HOST=db.ejemplo.local MIAPP_TITULO="Mi aplicación de ejemplo" ``` 3. Recargue la configuración de systemd y **reinicie** el servicio: ```bash sudo systemctl daemon-reload sudo systemctl restart devkron-fastcgi ``` Consideraciones: * El servicio no tiene recarga (`systemctl reload` falla con "Job type reload is not applicable"). Cada vez que cambie un valor hay que **reiniciarlo**; mientras no se reinicie, los programas siguen viendo el valor anterior. * systemd **no expande** variables como `$HOME` dentro de estos valores: se toman literalmente. * Si una línea de `Environment=` es inválida, systemd la ignora y lo registra en el journal (`Invalid environment assignment`). Revíselo con `journalctl -u devkron-fastcgi`. * Las variables quedan disponibles para todos los programas `.dkl` que atienda ese servicio, incluidos los archivos de inclusión.