I’ve been trying to schedule one of my python scripts through launchctl and am coming up against an error. The intention is that this runs at a given time past the hour, every hour.
I’ve created my plist, loaded it in launchctl but it’s not working properly. After doing some digging I debugged and got the following error messages: Traceback (most recent call last): File “/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/common/service.py”, line 72, in start self.process = subprocess.Popen(cmd, env=self.env, File “/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/subprocess.py”, line 854, in init self._execute_child(args, executable, preexec_fn, close_fds, File “/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/subprocess.py”, line 1702, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: ‘chromedriver’
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/Users/petersmith/Documents/Python/thenewsproject/link_getters/link_getter.py”, line 3, in
import myfile
File “/Users/directories/myfile.py“, line 51, in
browser = webdriver.Chrome(‘chromedriver’, options=chrome_options)
File “/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/chrome/webdriver.py”, line 73, in init
self.service.start()
File “/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/common/service.py”, line 81, in start
raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: ‘chromedriver’ executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home
I’ve updated the items in bold when pasting.
This is the line that it’s fussing about: browser = webdriver.Chrome(‘chromedriver’, options=chrome_options)
Now, chromedriver lives in my usr/local/bin folder and I’ve checked my path file and see: -bash: /Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/mysql/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Xamarin: No such file or directory
You can see in bold that it’s there so I’m a little lost.
Any ideas?
Advertisement
Answer
OK – so after a huge amount of searching I finally figured this out. There were actually two things causing me a problem when getting this working and they both related to the way that launchctl executes the work on behalf of the user.
The key things to remember are that launchctl will execute a process on your behalf and that means:
- It has it’s own PATH variable (which you need to update with your chromedriver location), and
- It executes your script from it’s own working directory, rather than the one your python script lives in. This will give you an issue for any other files you want to include or relative paths you use in your script(s)
To amend launchctl’s path you therefore need to run the following command from the terminal:
launchctl setenv PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Can’t remember if you then needed a restart or not but definitely unload and then reload your plist file
launchctl load ~Library/LaunchAgents/your.own.plist
You should then be good to go.
Fixing the second point is then a simple key-string pair to add yo your plist file
<key>WorkingDirectory</key> <string>/Users/you/path/to/mypythonfile/</string>
Hope this is helpful for others!