TLDR for those who googled and found this
In Catalina, launchd
can't read files or run scripts located inside your ~/Documents
folder. Just avoid putting your scripts there and rewrite your scripts not to read files in ~/Documents
. Creating a new file or symlink will work, though. See the answer below for details.
Original question
I came via this answer to help me create a script that will update a symlink every day.
And there was an article it links to teaching me how to use plist and launchctl
SO this is my plist com.journal.today.plist
which is installed in ~/Library/LaunchAgents
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.journal.today.plist</string>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/Users/kim/journals/stderr.log</string>
<key>StandardOutPath</key>
<string>/Users/kim/journals/stdout.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string><![CDATA[/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin]]></string>
</dict>
<key>WorkingDirectory</key>
<string>/Users/kim/journals</string>
<key>ProgramArguments</key>
<array>
<string>./makeTodaySym.sh</string>
</array>
</dict>
</plist>
When i check the stderr I saw the below
shell-init: error retrieving current directory: getcwd: cannot access parent
1 bash: ./makeTodaySym.sh: Operation not permitted
stdout.log was empty
How do I solve this?
My original script
#!/usr/bin/env bash
date=`date +"%Y-%m-%d %A"`
folder="." # replace with full path to desired folder
file="$folder/$date.md"
if [ ! -f "$file" ]; then
touch "$file"
echo "Created file: $file"
fi
ln -sf "$file" "$folder/today.md"
echo "Created link to file: $file"
After trying out jksoegaard answer, the last part of my plist looks like this:
<key>ProgramArguments</key>
<array>
<string>/Users/kim/journals/makeTodaySym.sh</string>
</array>
Latest change after taking jaume comment
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/kim/journals/makeTodaySym.sh</string>
</array>
Latest change
in the bash script
folder="$1" # replace with full path to desired folder
in the plist
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/kim/journals/makeTodaySym.sh /Users/kim/journals</string>
</array>
I have also tried
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/kim/journals/makeTodaySym.sh</string>
<string>/Users/kim/journals</string>
</array>
And now I get this
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Operation not permitted
/bin/bash: /Users/kim/journals/makeTodaySym.sh: Operation not permitted
thanks to @jaume with great patience, he/she/they have helped me get to the point where I realized that the only thing that worked was to move away from the Documents folder in Catalina.
I did find this link https://discussions.apple.com/thread/250719819?answerId=251683647022#251683647022 suggesting to create a fake bash clone, but I didn't try.
Also a big thank you to @nohillside
One useful thing I learn is to load and unload plist without restarting laptop
first unload
launchctl unload ~/Library/LaunchAgents/com.test.today.plist
then load
launchctl load -w ~/Library/LaunchAgents/com.test.today.plist
Best Answer
Analysis
After a long chat session, it turns out that the root of the problem was that
bash
can't fully access the Documents folder. The OP had shortened the actual path formakeTodaySym.sh
: instead of being located in/Users/kim/journals
, the script resides in a subfolder of~/Documents
.The Documents folder is sandboxed, as explained in this Apple document:
and
bash
can't read its contents from within the.plist
file.Two solutions
Place the script outside of
~/Documents
Interestingly enough, although
bash
can't read the contents of the Documents folder, it can write to it.So one solution is to move
makeTodaySym.sh
outside of~/Documents
. For instance, if placed in/Users/kim/bin/makeTodaySym.sh
, this should work:(Tested on macOS 10.15.5 Catalina.)
Grant full disk access to
bash
Another solution is give
bash
full disk access. Just add/bin/bash
to System Preferences>Security & Privacy>Privacy>Full Disk Access.Note that even with full disk access, permissions would prevent
bash
from reading arbitrary files in the file system, but you have one fewer level of protection.(Tested on macOS 10.15.5 Catalina.)
Two suggestions
I'd suggest that you do the following two changes to your configuration:
Remove reference to working directory
I've noticed that setting a working directory in the
.plist
file:causes this error:
Your script doesn't need the
WorkingDirectory
key to successfully create the symlink, so you may want to remove it to get rid of the error.Create symlink with relative path
Your script creates the symlink:
with an absolute path:
To may want to use:
instead to create a relative symlink that is easier to read:
Full path in plist file
It's important to note that providing the full path for
makeTodaySym.sh
(as explained in jksoegaard's answer) was a necessary change for the.plist
to work properly, as relative paths are not supported.