I'm writing a major mode to interface with a popular but clunky Monte Carlo program. I've also written a script that makes the interface a little more tolerable, and have written the following simple Lisp function to run that script within Emacs:
(defun run-phits ()
"Run phits-command on the current buffer asynchronously, displaying output in a new buffer and placing output files in the same directory as the current buffer's file."
(interactive)
(let ((default-directory (file-name-directory buffer-file-name)))
(async-shell-command (concat phits-command buffer-file-name))))
Whenever I run the value of phits-command
(the name of the script plus a space) on a file in a regular terminal buffer, it works fine.
Whenever I hit M-x run-phits
in a buffer of the same file, I get an internal error from the program I'm invoking that seems to be related to path-setting:
Fission_barrier_table_PhysRevC_91_024310.dat is missing in data folder
Error : input data file for multiplier does not exist.
file name = c:/phits/data/multiplier/m211.inp
The file it's talking about very much does exist. Evidently, c:/
is somehow internally aliased to the install directory of the program in a way that doesn't work with Emacs (I'm on Linux, to be clear; this must be happening because the same program works from the terminal). It doesn't work typing the command into M-!
either; I copied-and-pasted the command name from the line of *Messages*
that mentioned the error to the terminal and it worked flawlessly.
Removing the complexity of the script and using the default calling method of redirecting the file to the executable doesn't work either; here's the script in any case:
#!/bin/bash
phitsin_path="/home/dnw/PHITS/phits326A/phits/phits.in"
phits_MPI="/home/dnw/PHITS/phits326A/phits/bin/phits326_lin_mpi.exe"
phits_OMP="/home/dnw/PHITS/phits326A/phits/bin/phits326_lin_openmp.exe"
phits_single="/home/dnw/PHITS/phits326A/phits/bin/phits326_lin.exe"
while getopts ":MOh" option; do
case $option in
\?) echo -n "phits: unrecognized argument "
echo -n ${OPTARG}
echo "; see phits -h for help."
exit;;
M) # borrowed from calandoa on SO
nextopt=${!OPTIND}
if [[ $nextopt != -* && $nextopt != ${@: -1} ]] ; then
OPTIND=$((OPTIND + 1))
np=$nextopt
else
np=$(nproc --all)
fi
echo "file = $(readlink -f ${@: -1})" > ${phitsin_path}
mpirun -np ${np} ${phits_MPI}
exit;;
O) ${phits_OMP} < ${@: -1}
exit;;
h) echo "phits: nicer command-line interface to JAEA's Particle Heavy Ion Transport code System"
echo "Usage: phits -[MOh] [file]"
echo "Options:"
echo " none: run the standard PHITS single-core binary on [file]"
echo " -M [proc]: copy the path of [file] to phits.in and run a PHITS MPI binary on all cores of the current machine. If specified, use [proc] processes; otherwise, use every core."
echo " -O: run a PHITS OpenMP binary on [file]."
echo " -h: display this message."
exit;;
esac
done
# no option given; use single-thread binary
if [[ -n $1 ]] ; then
${phits_single} < $1
else
echo "Error: no input file specified."
fi
(Just checked that it's not the redirection by getting the MPI switch working; same error)
What subtle internal differences are there between Emacs spinning up a shell and running a script and my doing the same in M-x term
? The program in question is a million lines of FORTRAN in a style straight out of 1965, very much "real programmer" stuff, so there's little chance of me chasing down what the program is doing internally.
c:/
stuff coming from? You say: "Evidently, c:/ is somehow internally aliased to the install directory of the program in a way that doesn't work with Emacs " - that is not at all evident to me. On what do you base that statement? And which program are you referring to in the sentence above? You are talking about a command that you cut-and-pasted from the*Messages*
buffer: what command is that? Please edit your question and add all that information.