5

I'm on macOS (the same happens on Ubuntu). Here is my default/current shell:

$ ps -p $$
  PID TTY           TIME CMD
 5835 ttys002    0:00.13 -bash

Then, here is my document foo.tex:

\documentclass{article}
\begin{document}
\immediate\write18{ps -p $$ > stdout}
\end{document}

I'm compiling it and then checking the output:

$ pdflatex --shell-escape foo.tex && cat stdout
...
PID TTY           TIME CMD
 6876 ttys002    0:00.00 sh -c ps -p $$ > stdout

As you see, the shell is sh, instead of bash. How to fix this? I need bash to be executed by \write18.

yegor256
  • 12,021
  • 4
    I don't think there is any way to control that (maybe from lualatex but I doubt it from pdflatex) – daleif Oct 12 '23 at 07:52
  • 1
    The LaTeX2e unofficial reference manual (https://latexref.xyz/_005cwrite18.html) mentions "The shell_command text is always passed to /bin/sh on Unix-like operating systems, and the DOS command interpreter cmd.exe on Windows. Any different shell set by the user, and the SHELL environment variable, is ignored." This does mean that it probably is not actually sh but whatever /bin/sh symlinks to (on my Ubuntu that is dash), and also that you can change it by modifying the symlink. – Marijn Oct 12 '23 at 08:55

1 Answers1

9

You can invoke bash as part of the command, for example


\immediate\write18{bash -c 'echo \ current shell is: $0'}
\bye

produces a terminal output

$ pdftex --shell-escape file
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdftex)
 \write18 enabled.
entering extended mode
(./file.tex current shell is: bash
 )
No pages of output.
Transcript written on file.log.

Compare with

\immediate\write18{echo \ current shell is: $0}
\bye

which shows sh as the shell

$ pdftex --shell-escape file
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdftex)
 \write18 enabled.
entering extended mode
(./file.tex current shell is: sh
 )
No pages of output.
Transcript written on file.log.
David Carlisle
  • 757,742
  • This works, but I have to do something with apostrophes inside the command, for example: echo 'Hello, world!'. Maybe you can suggest how to "escape" them correctly? – yegor256 Oct 12 '23 at 10:13
  • 1
    you can use " as the outer quotes (if you need both then it's a bit harder), but for ' then \immediate\write18{bash -c "echo 'hello world'"} works @yegor256 – David Carlisle Oct 12 '23 at 10:32
  • You can also base64 en/decode your command and pipe it to bash. Check it out. – Ben Thul Oct 12 '23 at 20:57