Obtener la variable de entorno en C++
-
Utilice la función
std::getenv
para acceder a la variable de entorno en C++ - Utilizar rutinas de comprobación personalizadas para verificar los valores válidos de las variables de entorno
Este artículo explicará varios métodos de cómo obtener la variable de entorno en C++.
Utilice la función std::getenv
para acceder a la variable de entorno en C++
getenv
es una función compatible con POSIX implementada en la biblioteca estándar de C, que puede ser importada en el archivo fuente de C++ utilizando la cabecera <cstdlib>
. La función toma la cadena de caracteres como único argumento y busca el nombre de la variable de entorno que sea igual.
Las variables de entorno se representan convencionalmente con todas las letras mayúsculas, pero getenv
sigue requiriendo que la cadena del argumento no tenga letras minúsculas, ya que no coincidiría con el nombre de la variable aunque esté definida en el entorno del programa. La función devuelve el tipo char*
donde se almacena el valor de la variable correspondiente.
Fíjate en que asignamos el valor de retorno de getenv
a la variable const char*
porque necesitamos asegurarnos de que el programa no modifica esa ubicación; de lo contrario, se producirá un comportamiento indefinido.
#include <cstdlib>
#include <iostream>
#include <string>
using std::cerr;
using std::cout;
using std::endl;
using std::getenv;
using std::string;
const char *ENV_VAR = "HOME";
int main() {
const char *tmp = getenv("HOME");
string env_var(tmp ? tmp : "");
if (env_var.empty()) {
cerr << "[ERROR] No such variable found!" << endl;
exit(EXIT_FAILURE);
}
cout << "HOME : " << env_var << endl;
exit(EXIT_SUCCESS);
}
Producción :
HOME : /home/username
También es importante no pasar el valor devuelto por la función getenv
directamente al constructor std::string
, ya que podría lanzar un fallo de segmentación cuando la función getenv
no consiga calcular ninguna variable de entorno.
Este problema está causado aquí dentro de la implementación del código del constructor std::string
que llama a la función std::char_traits::length()
bajo el capó. Esta última función causará un comportamiento indefinido si se le pasa nullptr
como argumento. Así, se da el escenario en el que getenv
puede devolver nullptr
cuando no se encuentra la variable de entorno, y si se la pasamos al constructor string
, se forma el código erróneo.
#include <cstdlib>
#include <iostream>
#include <string>
using std::cerr;
using std::cout;
using std::endl;
using std::getenv;
using std::string;
const char *ENV_VAR = "HOME";
int main() {
// Erroneous
string env_var(getenv("HOME"));
if (env_var.empty()) {
cerr << "[ERROR] No such variable found!" << endl;
exit(EXIT_FAILURE);
}
cout << "HOME : " << env_var << endl;
exit(EXIT_SUCCESS);
}
Utilizar rutinas de comprobación personalizadas para verificar los valores válidos de las variables de entorno
Uno de los escollos más peligrosos cuando se accede a las variables de entorno es verificar el valor recuperado. Tenga en cuenta que estas variables pueden ser manipuladas por el atacante fuera del ámbito de nuestro programa. Por lo tanto, es necesario que haya una sanitización adicional de estos valores para asegurar la ejecución correcta y segura del programa.
Estas rutinas de comprobación dependen en su mayoría del programa y deben ser manejadas de forma diferente para cada caso. En el siguiente ejemplo, demostramos el escenario en el que asumimos que el valor de la cadena no debe tener ningún espacio y, si lo tiene, extraemos la subcadena antes del primer carácter de espacio. De este modo, evitamos cualquier valor de entrada irregular del entorno del sistema. Observa que el algoritmo std::find
se utiliza para buscar un carácter en la cadena
, y devuelve string::npos
si no se encuentra la char
especificada.
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <string>
using std::cerr;
using std::cout;
using std::endl;
using std::find;
using std::getenv;
using std::string;
const char *ENV_VAR = "HOME";
int main() {
const char *tmp = getenv(ENV_VAR);
string env_var(tmp ? tmp : "");
if (env_var.empty()) {
cerr << "[ERROR] No such variable found!" << endl;
exit(EXIT_FAILURE);
}
// Env Variable Value Sanitization
int pos = env_var.find(' ');
if (pos != string::npos) env_var = env_var.substr(0, pos);
cout << "HOME : " << env_var << endl;
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook