4

This is very frustrating. I can obtain my Linux group ID and assign it to a Latex counter.

When using the \bash..\END construct it works, but when using splice construct it does not work. I'll show MWE to explain more.

This works. I get the group ID from bash and set it to a Latex counter:

\documentclass{article}
\usepackage{bashful}
\newcounter{c}
\begin{document}
\bash
id -g
\END
\setcounter{c}{\bashStdout}

my group ID is \arabic{c}
\end{document}

compile pdflatex -shell-esc foo.tex and the PDF file shows

      my group ID is 1000

This does not work:

\documentclass{article}
\usepackage{bashful}
\newcounter{c}
\begin{document}
\setcounter{c}{\splice{id -g}}
my group ID is \arabic{c}
\end{document}

The compile error is

(/usr/local/texlive/2015/texmf-dist/tex/context/base/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
)
! Missing number, treated as zero.
<to be read again> 
\immediate 
l.8 \setcounter{c}{\splice{id -g}}                                    
? 

It looks like the counter is being set before bash is run and returned the 1000 value. So I need to tell it to expand before? I do not understand the expand commands, but I tried

  \expandafter\setcounter{c}{\splice{id -g}}

and

  \setcounter{c}{\expandafter\splice{id -g}}

but nothing is working. It is clearly an evaluation order issue. Is there a way to make splice work in the above? I'd like to learn why it is not working.

Package reference is here

This is what the documentaion says about splice

Mathematica graphics

Nasser
  • 20,220
  • The value argument of \setcounter has to expand to a number, not be some arbitrary non expandable code that eventually would typeset a number, \setcounter{c}{\def\foo{3}\foo} doesn't work either. – David Carlisle Jul 29 '15 at 09:15
  • why make it so complicated your value for your group id presumably doesn't change so why require shell escape to look it up every time? – David Carlisle Jul 29 '15 at 09:16
  • @DavidCarlisle that was just an example. I am using the bash command to obtain different information. But using id -g for illustrations. – Nasser Jul 29 '15 at 09:20
  • OK but It's unlikely to work inside \setcounter I would guess. – David Carlisle Jul 29 '15 at 09:21
  • @DavidCarlisle Ok, thanks. I am switching to egrep \shellcommand which works! but it has problem when I use breqn package, which I must use. I posted separate question on that. Latex is so hard. – Nasser Jul 29 '15 at 09:23
  • @Nasser No, it isn't hard. It may be difficult to get things it has not been thought for. – egreg Jul 29 '15 at 11:10

1 Answers1

3

The working of \splice is easy to explain:

% bashful.sty, line 232:
\newcommand\splice[1]{%
  \bashIV{#1}%
  \expandFileName@BL{\BL@stdoutFile}%
  \CatchFileDef{\BL@file@contents}{\BL@stdoutFile}{\relax}%
  \ignorespaces\BL@file@contents\unskip
}

The first thing it does is \bashIV:

% bashful.sty, line 211:
\newcommand\bashIV[1]{%
  \logBL{BashIV: begin}%
  \makeDirectory@BL
  \generateScriptFile@BL{#1}\relax
  \executeScriptFile@BL
  \logBL{BashIV: done}%
}%

The command writes out a script that's executed as we see from the definition of \executeScriptFile@BL:

% bashful.sty, line 299:
\newcommand\executeScriptFile@BL{%
  \edef\command@BL{\BL@shell \space \BL@scriptFile}%
  \if@hide@BL@
    \logBL{Adding a "cd command"}%
    \edef\command@BL{cd \directory@BL;\command@BL}
  \fi%
  \edef\command@BL{\command@BL \space >\BL@stdoutFile \space 2>\BL@stderrFile}%
  \edef\command@BL{\command@BL \space || echo $? >\BL@exitCodeFile}%
  \edef\command@BL{\BL@shell\space -c "\command@BL"}%
  \logBL{Executing:^^J \command@BL}%
  \immediate\write18{\command@BL}%
}%

The standard output is redirected to \BL@stdoutFile (which stands for a uniquely named file with extension .stdout.

Such a file is read in with \CatchFileDef and its contents is stored in \BL@file@contents for printing it, as testified by \ignorespaces and \unskip.

There's no real way to make this work in the argument to \setcounter that should be something that expands to a number, not to the instructions for printing a number.

You could define a different command:

\makeatletter
\newcommand{\splicesave}[2]{%
  \bashIV{#1}%
  \expandFileName@BL{\BL@stdoutFile}%
  \CatchFileDef{#2}{\BL@stdoutFile}{}% \relax was redundant
}
\makeatother

and do

\splicesave{id -g}{\foo}
\setcounter{c}{\foo}
egreg
  • 1,121,712