YES: There is a way to tell an already running x-program to open a file from bash!
So, following a tip from StataCorp's technical support folks, it turns out that xdotool (which can be installed with sudo apt install xdotool, if it is not already on your system) offers a solution to exactly the kind of problem in my question. From the project website:
xdotool lets you simulate keyboard input and mouse activity, move and resize windows, etc. It does this using X11’s XTEST extension and other Xlib functions.
⚠️ Note: If you are using Wayland, please be aware this software will not work correctly. ⚠️
With xdotool, you can search for windows and move, resize, hide, and modify window properties like the title. If your window manager supports it, you can use xdotool to switch desktops, move windows between desktops, and change the number of desktops.
To solve my problem with xdotool, I needed to create an xdotool script which I am calling statadoc.xdo (updated to reflect different behavior with window IDs since I first wrote this answer):
#!/usr/bin/xdotool
search --name "Stata/MP" type --delay 1 --window %2 '$1 ' '$2 '
search --name "Stata/MP" key --window %2 Return
A few comments about this short script:
- The path may be something other than
/usr/bin/xdotool, so be sure to confirm that with which xdotool or similar.
- The second line will partially match the name
"Stata/MP 17.0" with the string supplied above. This is useful, so that, for example, upgrading the version to 17.1, or 18.x won't break the script. The search command identifies the X-application window I want to interface with.
xdotool scripts accept arguments, following bash-like $1, $2, etc. conventions.
- The
type command literally types the provided text—in my case, the contents of the two supplied $1 and $2 string arguments in the 1st (and in my case only) window identified by the search command on line 2.
- The
key command sends an <ENTER> (or <RETURN> if you prefer) to the same Stata window.
Now let's look at my modified launch script, which calls statadoc.xdo in the third to last line (I have added a section in front to recognize whether the supplied argument indicates particular Stata file types—different use commands are needed to gracefully handle each… my example is not complete, but these are the file types I use in the majority of my work):
#!/bin/bash
# Check whether there IS NOT an argument. If not, set an empty
# prefix value by default.
if [ -z "$1" ]
then
prefix=" "
# Otherwise, set prefix to "use ", and then check whether file
# name ends in .hlp, .sthlp, .ado, .do, or .gph
else
prefix="use "
if [ ${1##*.} = "hlp" ] || [ ${1##*.} = "ado" ] || [ ${1##*.} = "do" ]
then
# If the filename DOES end in one of those four prefixes then
# change prefix to "doedit" so Stata opens the document with
# the do-file editor.
prefix="doedit "
fi
# If the filename ends in .gph, then change prefix to "graph use " so
# Stata opens the document with the graph viewer/editor.
if [ ${1##*.} = "gph" ]
then
prefix="graph use "
fi
# If the filename ends in .sthlp or hlp, then change prefix to "view " so
# Stata opens the document with the viewer.
if [ ${1##*.} = "sthlp" ] || [ ${1##*.} = "hlp" ]
then
prefix="view "
fi
break
fi
Check if xstata-mp v18 is running
exit_code_pidof_xstata_mp=$(pidof /usr/local/stata18/xstata-mp)
if xstata-mp v18 IS NOT running, then launch it
if [ -z "$exit_code_pidof_xstata_mp" ]
then
/usr/local/stata18/xstata-mp
fi
Bring Stata to the front, and call statadoc.xdo with the prefix as
the first argument, and the supplied file path as the second argument
/usr/share/stata18/bin/statadoc.xdo "$prefix" " $1"
wmctrl -ia "$(wmctrl -lp | grep "$(pgrep /usr/local/stata18/xstata-mp)" | tail -1 | awk '{ print $1 }')"
exit > /dev/null
Note: This is a solution for Gnome running on Xorg.