Jump to content

External Script Says "python3 command requires the command line developer tools"?


Recommended Posts

l'm really confused. I created a file filter workflow that calls a script file that then calls a python script. I can run the script from the command line with no problems at all. When I try to run the Alfred workflow I get a pop up that says the python3 command requires the command line developer tools (see the attached image). Why am I getting this message when the script runs perfectly fine outside of Alfred?

Screen Shot 2021-10-25 at 1.57.03 AM.png

Link to comment

Alfred doesn’t use the same environment as your shell. You have to align whatever you do to get python3 working.

 

The solution depends on how you’re calling the script, so it’s not possible to say how to fix it unless you share your Workflow.

Link to comment
2 hours ago, alfredclough said:

I assumed the shell script would create a shell and setup the variables properly

 

No shell script does that. Any external data they get is from the enclosing shell from where you ran them, which in turn would have need to load its data from its startup files.


To fix it, either figure out where python3 is installed and use its full path (e.g. /usr/bin/python3 list_files.py "$@") or call the script directly and use that path as the shebang.


If you’re using something like a Python version manager, do in the shell script whatever you do in your shell’s startup files to load that environment.

Link to comment
2 hours ago, alfredclough said:

Well I assumed the shell script would create a shell and setup the variables properly

 

It's more complicated than that. Shells load different startup files depending on whether they're running interactively (i.e. in a terminal emulator) or not (i.e. in Alfred). The normal configuration is that all your customisations are not loaded in a non-interactive shell.

 

If you want something in /usr/local/bin to be run, you either need to call it by its full path (i.e. /usr/local/bin/python3 ..., not just python3 ..), or to put export PATH=/usr/local/bin:$PATH at the top of your shell script.

 

Edited by deanishe
Link to comment

In case it helps anyone else, in my case I ended up solving it by adding this line to the shell script that runs the python script:

 

source ~/.bash_profile

 

This sets the path to the default shell path.  This way the script will automatically update the path is uses to search for python3 with future updates and I don't have to hardcode a full path to the specific version of python. Now it runs without any issues.

Edited by alfredclough
Link to comment
Just now, alfredclough said:

and I don't have to hardcode a full path to the specific version of python. Now it runs without any issues.

 

But it also makes it so you can never share the Workflow with anyone else. It may not even work between your own machines. Furthermore, you’re loading your entire shell configuration—that will be slower than just running the commands to load the necessary Python environment.

 

Not that your solution is wrong, but you should be aware of the tradeoffs.

Link to comment
3 hours ago, alfredclough said:

This way the script will automatically update the path is uses to search for python3 with future updates and I don't have to hardcode a full path to the specific version of python


Instead, you've made your workflow dependent on your shell configuration, which is a much worse solution.

 

There is a good reason your shell config files aren't loaded in non-interactive shells.

 

Now you have to worry about your workflow when editing your shell config. And like Vítor says, your workflow won't work on another machine that doesn't have a similarly-configured shell.

Edited by deanishe
Link to comment

If this was a workflow to be shared, I'd agree. In my case, whenever I updated python3 on my machine it will automatically update the path in my .bash_profile so I'll never need to update the Alfred workflow. The only other option is having to update the workflow every time I update python. that's not horrible, but it is an extra step. And my .bash_profile only includes the PATH configuration so loading it doesn't affect performance. So I'm not sure how any other solution would be better in this case. And it will work on all my machines because they will all have the PATH setting updated when Python3 is installed or updated.

 

But if the workflow was going to be shared that is completely different. In that case I would have written it in python2.

Link to comment
1 hour ago, alfredclough said:

The only other option is having to update the workflow every time I update python

 

 Unless you're doing something weird like running your workflows with pyenv, when you update Python, the new version will replace the old one and the executable will be in exactly the same place.

 

1 hour ago, alfredclough said:

So I'm not sure how any other solution would be better in this case.

 

Well, for one thing, the other solutions don't introduce external dependencies, and for another, they're how you're actually supposed to solve this problem.

 

What you are doing is basically misusing bash. The entire purpose of ~/.bashrc is to contain stuff that's only loaded in interactive shells – that's why bash isn't automatically loading it in Alfred to begin with – and by breaking that rule, you're setting yourself up for problems further down the road.

 

2 hours ago, alfredclough said:

But if the workflow was going to be shared that is completely different. In that case I would have written it in python2.

 

That's not a good solution, either, seeing as Python 2 is no longer in development. Only a matter of time before that breaks.

 

There is no obviously best solution for writing and sharing Python workflows at the moment. All the same, there's no reason to deliberately make one unshareable by sourcing your ~/.bashrc.

Link to comment
  • 4 weeks later...
6 hours ago, Hans-Pe said:

For both interactive and non-interactive shells /etc/zshenv is executed.

 

/etc/zshenv calls /usr/libexec/path_helper

 

This program builds $PATH from the contents of /etc/path and /etc/path.d, see man path_helper.

And /etc/path contains /usr/local/bin.

Yes, it sounds complicated.

 

None of those exist on my Catalina system.

Link to comment
4 hours ago, deanishe said:

 

None of those exist on my Catalina system.

Sorry deanishe,

I deleted my original post after a few minutes, because I realized the nonsense (too late in the evening) , but you were faster.

I confused /etc/zshenv with /etc/zprofile:

  • /etc/zshenv is run for all zsh sessions 
  • /etc/zprofile runs only for interactive shells and executes path_helper

A simple workflow with run script bash or zsh

echo -n $PATH

yields

[Run Script] Passing output '/usr/bin:/bin:/usr/sbin:/sbin'

 and confirms what you wrote already.

 

I am running BigSur and I have installed miniconda:

 

~ % whence -va python3 
python3 is /Users/xx/miniconda3/bin/python3
python3 is /usr/bin/python3


 

~ % for p in $(whence -a python3)
for> print "$p is $($p --version)"
/Users/xx/miniconda3/bin/python3 is Python 3.9.7
/usr/bin/python3 is Python 3.8.9


 

So if in an Alfred run script  I code   

python3 ./some.py

python 3.8.9 gets called. If I submit the same command in Terminal, python 3.9.7 gets called. 

 

This is what I or others have to consider if we want to use Python in Alfred.

 

 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...