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
:
#!/usr/bin/xdotool
search --name "Stata/MP"
type --window %1 '$1 ' '$2'
key --window %1 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):
# Check whether there IS NOT an argument. If not, do nothing.
if [ -z "$1" ]
then
break
# Otherwise, set prefix to default value, and then check
# whether file name ends in .hlp, .sthlp, .ado, .do, or .gph
else
prefix="use "
if [ ${1##*.} = "hlp" ] || [ ${1##*.} = "sthlp" ] || [ ${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 "doedit" so
# Stata opens the document with the graph viewer/editor.
if [ ${1##*.} = "gph" ]
then
prefix="graph use "
fi
break
fi
# Check if xstata-mp v17 is running
exit_code_pidof_xstata_mp=$(pidof /usr/local/stata17/xstata-mp)
# if xstata-mp v17 IS NOT running, then launch it with argument $1
if [ -z "$exit_code_pidof_xstata_mp" ]
then
/usr/local/stata17/xstata-mp -q $1; exit >/dev/null
# but if xstata-mp v17 IS running, then bring it to front instead
else
# First, call statadoc.xdo with the prefix as the first argument,
# and the supplied file path as the second argument
/usr/share/stata17/bin/statadoc.xdo "$prefix" " $1"
wmctrl -ia "$(wmctrl -lp | grep "$(pgrep /usr/local/stata17/xstata-mp)" | tail -1 | awk '{ print $1 }')"; exit > /dev/null
fi
Note: This is a solution for Gnome running on Xorg.