Ottieni variabile d'ambiente in C++

Jinku Hu 12 ottobre 2023
  1. Usa la funzione std::getenv per accedere alla variabile d’ambiente in C++
  2. Utilizzare routine di controllo personalizzate per verificare i valori delle variabili di ambiente validi
Ottieni variabile d'ambiente in C++

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);
}
Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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