1

This question is a followup to this thread in which @egreg provided a command \getenv to access a system environment variable. In response to my comment, he suggested a way to expand his script so that it would deal with the possibility that the environment variable was not defined. I believe I've followed his suggestion in the script below, and expected the \getenv command in the body of the email to return UNDEFINED, but it returns empty. Could you please explain how to get it to do so? Thanks!

\documentclass{article}
    \usepackage{catchfile}
    \newcommand{\getenv}[2][]{%
      \CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{}%
      \ifx\temp\empty\def\temp{UNDEFINED}\fi
      \if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
    \begin{document}
        test \getenv{NOT_DEFINED}
    \end{document}
Leo Simon
  • 2,199

2 Answers2

2

If you add \typeout{\temp} you will see that \temp is equal to \par, so rather than testing for \empty you need to test for \par. A simple \ifx\temp\par does not work but thanks to Why can't I compare a string with \par?, the following does:

\documentclass{article}
\usepackage{catchfile}
\def\apar{\par}
\newcommand{\getenv}[2][]{%
  \CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{}%
  \ifx\temp\apar\def\temp{UNDEFINED}\fi
  \if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
\begin{document}
    test \getenv{NOT_DEFINED}
\end{document}
2

You added \ifx\temp\empty\def\temp{UNDEFINED}\fi to the wrong code in the linked answer.

The comment was “Add before the \if\relax lines…” and so this was referring to the most recent version:

\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}%
    \ifx\temp\empty\def\temp{UNDEFINED}\fi
    \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 "" ) }}%
      \ifx\temp\empty\def\temp{UNDEFINED}\fi
      \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}%
      \ifx\temp\empty\def\temp{UNDEFINED}\fi
      \if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
  \fi
\fi

\begin{document}

\getenv{SHELL}

\getenv{NOT_DEFINED}

\end{document}

enter image description here

Note the \endlinechar=-1 part in the \CatchFileDef lines, that remove the unwanted end-of-line character. You may need to use

\immediate\write18{rm -f \jobname.tmp;kpsewhich --var-value #2 > \jobname.tmp} 

with XeTeX, depending on your shell setup.

egreg
  • 1,121,712