Ottieni variabile d'ambiente in C++
-
Usa la funzione
std::getenv
per accedere alla variabile d’ambiente in C++ - Utilizzare routine di controllo personalizzate per verificare i valori delle variabili di ambiente validi
Questo articolo spiegherà diversi metodi su come ottenere la variabile di ambiente in C++.
Usa la funzione std::getenv
per accedere alla variabile d’ambiente in C++
getenv
è una funzione conforme a POSIX implementata nella libreria standard C, che può essere importata nel file sorgente C++ usando l’intestazione <cstdlib>
. La funzione accetta la stringa di caratteri come unico argomento e cerca il nome della variabile di ambiente che è uguale.
Le variabili d’ambiente sono convenzionalmente rappresentate con tutte le lettere maiuscole, ma getenv
richiede comunque che la stringa dell’argomento non abbia lettere minuscole poiché non corrisponderebbe al nome della variabile anche se è definita nell’ambiente del programma. La funzione restituisce il tipo char*
in cui è memorizzato il valore della variabile corrispondente.
Notare che assegniamo il valore di ritorno della variabile getenv
alla variabile const char*
perché dobbiamo assicurarci che il programma non modifichi quella posizione; in caso contrario, risulterà in un comportamento indefinito.
#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);
}
Produzione:
HOME : /home/username
È anche importante non passare il valore restituito dalla funzione getenv
direttamente al costruttore std::string
, poiché potrebbe generare un errore di segmentazione quando la funzione getenv
non riesce a calcolare qualsiasi variabile d’ambiente.
Questo problema è causato qui all’interno dell’implementazione del codice costruttore std::string
che chiama la funzione std::char_traits::length()
sotto il cofano. Quest’ultima funzione provocherà un comportamento indefinito se le viene passato nullptr
come argomento. Quindi, c’è lo scenario in cui getenv
può restituire nullptr
quando la variabile d’ambiente non viene trovata, e se la passiamo al costruttore string
, viene formato il codice errato.
#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);
}
Utilizzare routine di controllo personalizzate per verificare i valori delle variabili di ambiente validi
Una delle insidie più pericolose quando si accede alle variabili di ambiente è la verifica del valore recuperato. Nota che queste variabili possono essere manipolate dall’aggressore al di fuori dell’ambito del nostro programma. Pertanto, è necessaria un’ulteriore sanificazione di questi valori per garantire un’esecuzione corretta e sicura del programma.
Queste routine di controllo dipendono principalmente dal programma e dovrebbero essere gestite in modo diverso per ogni caso. Nell’esempio seguente, dimostriamo lo scenario in cui assumiamo che il valore della stringa non debba contenere spazi e in tal caso estraiamo la sottostringa prima del primo carattere di spazio. In questo modo, eludiamo qualsiasi valore di input irregolare dall’ambiente di sistema. Si noti che l’algoritmo std::find
è utilizzato per cercare un carattere nella stringa
, e restituisce string::npos
se il char
specificato non viene trovato.
#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