user202729 / plover_run_shell

Run a shell command from Plover.
GNU General Public License v3.0
5 stars 0 forks source link

Allow access to shell environment variables #3

Closed paulfioravanti closed 2 years ago

paulfioravanti commented 2 years ago

I use Plover Run Shell in my steno dictionaries to call scripts located in the same repo.

An example that makes a lot of use of it would be my command-applications.json dictionary, where I have outlines that run AppleScripts to activate macOS applications that look like the following:

"KRO*EPLZ": "{:COMMAND:SHELL:osascript $HOME/steno/steno-dictionaries/src/command/application/activate-application.scpt \"Google Chrome\"}",

The $HOME/steno/steno-dictionaries path is the location where I personally have placed the repo, but it would be great if I was able to set it as an environment variable, like $STENO_DICTIONARIES, in a shell .rc file so that others could use the outlines without needing to go and manually change the location path to wherever they've cloned the repository.

So, I think the ideal would be to be able to change the outline to be something like:

"KRO*EPLZ": "{:COMMAND:SHELL:osascript $STENO_DICTIONARIES/src/command/application/activate-application.scpt \"Google Chrome\"}",

(Currently changing the command to this breaks the command as $STENO_DICTIONARIES cannot be read.)

Would allowing access to local shell environment variables in the subprocess be possible? The os.system documentation would seem to say that:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function.

...with instructions on how to replace it here.

I'm not a Python programmer, so I'm not sure about whether this is a good idea or not, but what do you think about allowing access to shell environment variables, or perhaps even having some kind of config file where a user could specify a set of environment variables that they would like to have available in the subprocess?

user202729 commented 2 years ago

(previous revision was wrong.)

If Plover can't read it, it's because you didn't pass the environment variable to Plover correctly. (indeed, it could read $HOME)

You didn't show your bashrc or anything so I can only guess some possible causes...

For the subprocess issue, Plover command can only take string arguments; and os.system is strictly equal to passing string to Popen (with some other options) – https://stackoverflow.com/questions/4813238/difference-between-subprocess-popen-and-os-system#4813571 so the functionality would be the same.

paulfioravanti commented 2 years ago

Thanks for the response.

For the record, my ~/.bashrc file contains:

export STENO_DICTIONARIES="$HOME/steno/steno-dictionaries"

and my ~/.bash_profile just brings in everything from .bashrc:

# Import .bashrc settings
if [ -f ~/.bashrc ]; then
  source ~/.bashrc
fi

I can confirm that it's been exported properly:

$ env | grep STENO
STENO_DICTIONARIES=/Users/paul/steno/steno-dictionaries

So, yeah, I'm a bit puzzled as to why the subprocess cannot seem to see that specific variable, yet can see others like $HOME. The command works as expected with the variable when running it directly from the command line:

$ osascript $STENO_DICTIONARIES/src/command/application/activate-application.scpt Slack

...but not when the command is in an outline (wrapping the command in bash -c as per the previous comment's revision didn't work either).

Anyway, I can understand why you wouldn't want to change what is there for compatibility reasons, and I cannot currently discount that the issue is something that potentially only affects my machine, so I'll continue looking into this and if I find a solution, I'll update this issue. Thanks!

Edited to add:

When I run the command through Python on the command line using os.system:

python -c "import os; os.system('osascript $STENO_DICTIONARIES/src/command/application/activate-application.scpt Slack')"

...it works as expected, adding to the confusion 🤷

user202729 commented 2 years ago
  1. In the last case, because the outermost quote is " bash will expand it before passing to Python.
  2. That doesn't really confirm the issue, does it? Check if it's exported instead, see e.g. https://unix.stackexchange.com/questions/390831/how-do-you-determine-whether-shell-variables-are-exported-or-not#390865
  3. Does it work when Plover is run from a shell? As I said above it's possible whatever started Plover does not take the environment variables, and I don't use Mac.
paulfioravanti commented 2 years ago

In the end, I was able to get this working by having the outline run the command using bash interactive mode:

"KRO*EPLZ": "{:COMMAND:SHELL:bash -ci 'osascript $STENO_DICTIONARIES/src/command/application/activate-application.scpt \"Google Chrome\"'}",

So, I guess for any macOS users who use Plover Run Shell, and who want to make use of environment variables defined in their .bashrc files, this is an incantation that would seem to work as expected.