Can I access system/environment variables from LaTeX? For instance, $HOME
If you have a recent TeX Live (2010 or later) or MiKTeX (v. 2.9), then the following works (and does not need the -shell-escape
command line option):
\usepackage{catchfile}
\newcommand{\getenv}[2][]{%
\CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{\endlinechar=-1}%
\if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
\getenv[\HOME]{HOME}
If you only say \getenv{VAR}
then the value of the variable is printed instead of being stored in a control sequence.
Not only HOME
can be used, but any environment variable and also the "pseudovariables" defined in the TeX kpathsea
system such as TEXMF
or TEXINPUTS
.
Note that this works only with pdflatex
. With other engines or older distributions, shell escape is needed. Of course LuaTeX has its methods for interacting with the system.
A version that works with all recent engines is
\documentclass{article}
\usepackage{ifxetex,ifluatex}
\ifxetex
\usepackage{catchfile}
\newcommand\getenv[2][]{%
\immediate\write18{kpsewhich --var-value #2 > \jobname.tmp}%
\CatchFileDef{\temp}{\jobname.tmp}{\endlinechar=-1}%
\if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
\else
\ifluatex
\newcommand\getenv[2][]{%
\edef\temp{\directlua{tex.sprint(
kpse.var_value("\luatexluaescapestring{#2}") or "" ) }}%
\if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
\else
\usepackage{catchfile}
\newcommand{\getenv}[2][]{%
\CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{\endlinechar=-1}%
\if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
\fi
\fi
\begin{document}
\getenv[\HOME]{HOME}\show\HOME
\end{document}
In the case of xetex
an auxiliary file \jobname.tmp
is written and -shell-escape
is necessary.
Note: the LuaTeX method has been suggested by Patrick Gundlach. If the variable is unset or not known to kpathsea
, the empty string will result.
UPDATE 2019
With recent and up-to-date TeX distributions, the following works with every engine (except, of course, Knuth TeX): pdflatex
, xelatex
, lualatex
, platex
and uplatex
. Unrestricted shell escape is not necessary.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\getenv}{om}
{
\sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 } { } \l_tmpa_tl
\tl_trim_spaces:N \l_tmpa_tl
\IfNoValueTF { #1 }
{
\tl_use:N \l_tmpa_tl
}
{
\tl_set_eq:NN #1 \l_tmpa_tl
}
}
\ExplSyntaxOff
\begin{document}
\getenv[\HOME]{HOME}\show\HOME
\end{document}
@egreg has already answered your question so I thought I'd not answer it. That is suggest not relying on environment variables for this. If the latex file just goes \includegraphics{figures/figure.pdf}
then if $HOME/figures//
is in TEXINPUTS environment variable or texmf.cnf
configuration setting then the file will be found without LaTeX explicitly needing to access the machine-specific information. This keeps machine specific information and directory structure in the kpathsearch system which is optimised to deal with that rather than the macro layer which tries as far as possible to avoid such issues.
Also for the specific case of home directory you can (on web2c systems on at least linux and windows/cygwin, but I assume the others too) use \string~/figures/figure.pdf
as kpathsea understands ~
as the home directory (but you have to pass it a literal ~
not the normal active definition for a non-breakable space, hence the \string
.