New solution starting from TeX Live 2024 ($TEXMF_OUTPUT_DIRECTORY)
Just access the environment variable named $TEXMF_OUTPUT_DIRECTORY.
Use sys_get_shell: https://tex.stackexchange.com/a/62032/250119 .
Credit: https://tex.stackexchange.com/a/707351/250119 .
Solution using currfile-abspath
Using currfile-abspath detailed in https://tex.stackexchange.com/a/54894/250119
(see the note regarding -recorder flag), it's possible to use \currfileabsdir to get the output directory, using the facts that
- Writing to a file will write it to the output directory by default
\input searches in the current -output-directory first
%! TEX program = xelatex
\documentclass{standalone}
\usepackage[abspath]{currfile}
\begin{document}
\ExplSyntaxOn
% write the content to a temporary file test.tex
\iow_new:N \myfile
\iow_open:Nn \myfile {test.tex}
\iow_now:Nn \myfile {
\tl_set:Nx \myoutputdir {\currfileabsdir}
}
\iow_close:N \myfile
% execute the content of that file
\input {test.tex}
% print the obtained output directory path to the PDF
\texttt{\myoutputdir}
\ExplSyntaxOff
\end{document}
It does require a temporary file, however.
Note that if in one compilation there is -recorder, then in the following compilation there's no -recorder, I think it's impossible to detect the change --
currfile-abspath package gets it wrong as well.
Attempting to write to \jobname.fls might do something, but on Windows I think multiple write to the same file is not allowed.
One option is to randomize the file name, but that does not work on MiKTeX (recorder file not updated online) and clutters the file system.
Note that you may want to rename test.tex to something sufficiently obscure, and possibly check if the file exists before writing. If you're not careful you might overwrite some important file.
Alternative using ps to get current process's command-line arguments
(because of some permission issue this does not work on Overleaf, but otherwise should work on most POSIX systems)
\ExplSyntaxOn
\sys_get_shell:nnN {ps~-o~args=~-p~$(ps~-o~ppid=~-p~$$)} {\cctab_select:N \c_other_cctab} \l_data_tl
\ExplSyntaxOff
Then \l_data_tl consist of the command-line of the TeX process (e.g. pdflatex --output-directory=/a/b/c main.tex)
but note that all the characters will have "other" catcode including spaces.
From this, parsing the string to get the output directory is a standard exercise. Note that the relevant flag might be written as...
-output-d=/path
-output-d=
-output-dir=/path
--output-dir=/path
--output-directory=/path
-output-d /path
-output-directory /path
--output-directory /path
As far as I can tell these are all the variants (all prefixes of output-directory longer than or equal to output-d are accepted), although I haven't checked with e.g. texdoc pdftex-changes.
Another alternative using find to look for the log file
Refer to David Carlisle's answer. Not recommended.
Another alternative
(completely untested)
if you don't have -recorder, first write the file then refer to How to obtain absolute path of a file (or maybe file_get_full_name function in expl3, I'm not sure) to get the path of the file. (although this might fail, output-directory is not necessarily searched in by kpsewhich)
Related answers:
pdftexthat keeps the value of the output directory. – egreg Feb 20 '16 at 11:42openout_aor something to write to any directories (for example/tmp/) then hard code it; or use https://tex.stackexchange.com/a/513810/250119 -- scontents to not use temporary file at all. – user202729 Nov 02 '21 at 02:51scontentspacakge. I wasn not aware of that package. – Peter Grill Nov 02 '21 at 07:34