Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

expand file names that have environment variables in their path

What's the best way to expand

${MyPath}/filename.txt to /home/user/filename.txt

or

%MyPath%/filename.txt to c:\Documents and settings\user\filename.txt

with out traversing the path string looking for environement variables directly? I see that wxWidgets has a wxExpandEnvVars function. I can't use wxWidgets in this case, so I was hoping to find a boost::filesystem equivalent or similar. I am only using the home directory as an example, I am looking for general purpose path expansion.

like image 267
Dan Avatar asked Dec 14 '09 18:12

Dan


People also ask

Which file contains environment variables?

User level Environment variables are mostly stored in . bashrc and . profile files in your Home folder.

How do I get a list of environment variables?

To list all the environment variables, use the command " env " (or " printenv "). You could also use " set " to list all the variables, including all local variables.

Which file contains environment variables in Windows?

The Windows System folder. A typical path is C:\Windows\System32. The Windows directory or system root. This corresponds to the %WINDIR% or %SYSTEMROOT% environment variables.

Which environment variable is used to set the PATH?

The PATH environment variable is an important security control. It specifies the directories to be searched to find a command. The default systemwide PATH value is specified in the /etc/profile file, and each user normally has a PATH value in the user's $HOME/.


3 Answers

For UNIX (or at least POSIX) systems, have a look at wordexp:

#include <iostream>
#include <wordexp.h>
using namespace std;
int main() {
  wordexp_t p;
  char** w;
  wordexp( "$HOME/bin", &p, 0 );
  w = p.we_wordv;
  for (size_t i=0; i<p.we_wordc;i++ ) cout << w[i] << endl;
  wordfree( &p );
  return 0;
}

It seems it will even do glob-like expansions (which may or may not be useful for your particular situation).

like image 125
MikeGM Avatar answered Oct 11 '22 21:10

MikeGM


On Windows, you can use ExpandEnvironmentStrings. Not sure about a Unix equivalent yet.

like image 21
Rob Kennedy Avatar answered Oct 11 '22 20:10

Rob Kennedy


If you have the luxury of using C++11, then regular expressions are quite handy. I wrote a version for updating in place and a declarative version.

#include <string>
#include <regex>

// Update the input string.
void autoExpandEnvironmentVariables( std::string & text ) {
    static std::regex env( "\\$\\{([^}]+)\\}" );
    std::smatch match;
    while ( std::regex_search( text, match, env ) ) {
        const char * s = getenv( match[1].str().c_str() );
        const std::string var( s == NULL ? "" : s );
        text.replace( match[0].first, match[0].second, var );
    }
}

// Leave input alone and return new string.
std::string expandEnvironmentVariables( const std::string & input ) {
    std::string text = input;
    autoExpandEnvironmentVariables( text );
    return text;
}

An advantage of this approach is that it can be adapted easily to cope with syntactic variations and deal with wide strings too. (Compiled and tested using Clang on OS X with the flag -std=c++0x)

like image 21
sfkleach Avatar answered Oct 11 '22 20:10

sfkleach