Switch based on whether or not an environment variable is set

When you execute a shell command, TeX sees it as if you had written the output of the command to a temporary (pseudo) file, and then read that file in. While reading that file, the usual rules apply: a line end is turned into a space, and an empty line is turned into a \par token. When the output of the command is empty, it is as if the file had an empty line, and that is turned into a \par. The usual trick is to set the \endlinechar parameter to -1, so that TeX doesn't insert anything at the end of a line, neither a \par token.

The second argument in \sys_get_shell:nnN is the <setup>, in which you can change these types of parameters before the command is executed and the pseudo file is read in, so you can do:

\sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 }
  { \int_set:Nn \tex_endlinechar:D { -1 } }
  \l_septatrix_env_tl

Putting that in egreg's \getenv code:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_septatrix_env_tl
\NewDocumentCommand \getenv { o m }
  {
    \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 }
      { \int_set:Nn \tex_endlinechar:D { -1 } }
      \l_septatrix_env_tl
    \IfNoValueTF {#1}
      { \tl_use:N \l_septatrix_env_tl }
      { \tl_set_eq:NN #1 \l_septatrix_env_tl }
  }
\ExplSyntaxOff

\begin{document}

\getenv[\HOME]{HOME}\show\HOME

\getenv[\HOMER]{HOMER}\show\HOMER

\end{document}

You can define \ifenvsetTF (this is a better name, in my opinion} by

\tl_const:Nn \c_getenv_par_tl { \par }

\NewDocumentCommand{\ifenvsetTF}{mmm}
 {
  \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #1 } { } \l_tmpa_tl
  \tl_if_eq:NNTF \l_tmpa_tl \c_getenv_par_tl { #3 } { #2 }
 }

Full example:

\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
   }
 }

\tl_const:Nn \c_getenv_par_tl { \par }

\NewDocumentCommand{\ifenvsetTF}{mmm}
 {
  \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #1 } { } \l_tmpa_tl
  \tl_if_eq:NNTF \l_tmpa_tl \c_getenv_par_tl { #3 } { #2 }
 }

\ExplSyntaxOff

\begin{document}

\getenv{LC_CTYPE}

\ifenvsetTF{LC_CTYPE}{SET}{UNSET}

\ifenvsetTF{BOZO}{SET}{UNSET}

\end{document}

enter image description here

However, note that variables set to empty value will trigger “unset” anyway (with this method and also with the \endlinechar method).

How to define an expl3 conditional?

\prg_new_protected_conditional:Nnn \septatrix_if_setenv:n {T,F,TF}
 {
  \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #1 } { } \l_tmpa_tl
  \tl_if_eq:NNTF \l_tmpa_tl \c_getenv_par_tl
   { \prg_return_false: }
   { \prg_return_true: }
 }

Full code

\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
   }
 }

\tl_const:Nn \c_getenv_par_tl { \par }
\prg_new_protected_conditional:Nnn \septatrix_if_setenv:n {T,F,TF}
 {
  \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #1 } { } \l_tmpa_tl
  \tl_if_eq:NNTF \l_tmpa_tl \c_getenv_par_tl
   { \prg_return_false: }
   { \prg_return_true: }
 }

\NewDocumentCommand{\ifenvsetTF}{mmm}
 {
  \septatrix_if_setenv:nTF { #1 } { #2 } { #3 }
 }

\ExplSyntaxOff

\begin{document}

\getenv{LC_CTYPE}

\ifenvsetTF{LC_CTYPE}{SET}{UNSET}

\ifenvsetTF{BOZO}{SET}{UNSET}

\end{document}