3

I want to use launchd to run bindfs commands at login, as root. I have a plist in /Library/LaunchAgents/loginsftpjailmount.plist (with chmod 600) and a shell script in /usr/local/bin/loginsftpjailmount.sh.

I should start by saying it works - if I change the bash script to run

mkdir /Users/Me/Desktop/itworks

then it successfully creates the directory "itworks", both on login and by running

sudo launchctl load /Library/launchAgents/loginsftpjailmount.plist

And the folder created is owned by root and I have to type in my password to delete it. When I manually run the bash script from the terminal using sudo, the bindfs command works.

So to summarize - I know the script works. I know the plist works. I know they work together with launchd. But the bindfs command doesn't run! I checked the system log with

sudo grep com.user /var/log/system.log

and it says it exits with error 127 (com.user is part of the label for my plist). I searched online and none of the solutions for error 127 work for me. For reference, two plists I have used are:

<?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.user.loginitem</string>
<key>ProgramArguments</key>
<array>
    <string>bash</string>
    <string>-c</string>
    <string>bash -c "bindfs /Volumes/BRIGHTRED/ServedDocuments /sftpjail/Documents"</string>
</array>
<key>RunAtLoad</key>
<true/>

and also

<?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.user.loginitem</string>
        <key>Program</key>
        <string>/usr/local/bin/loginsftpjailmount.sh</string>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>
  • I found my own answer. The problem is that bindfs is installed under /opt/local/bin and launchd cannot find it. So by simply changing my shell script to execute the full path, it runs. My shell script is now like "/opt/local/bin/bindfs directory1 directory2" instead of simply "bindfs directory1 directory2" But I have a new problem - it runs when I do sudo load manually, but doesn't run on login. – Kyle Mar 22 '17 at 23:57
2

The bindfs process has to be started with root privileges. Launching it as agent would prevent this.

So sudo launchctl unload ... and sudo launchctl remove ... (the subcommand remove removes the agent from the launchd database - the file won't get deleted!) the plist, move the plist to /Library/LaunchDaemons/ and reload it with sudo launchctl load ....

A properly named and composed org.user.bindfs.sftpjail.plist would look like this:

<?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>org.user.bindfs.sftpjail</string>
        <key>ProgramArguments</key>
        <array>
                <string>/opt/local/bin/bindfs</string>
                <string>/Volumes/BRIGHTRED/ServedDocuments</string>
                <string>/sftpjail/Documents</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/tmp/org.user.bindfs.sftpjail.err</string>
        <key>StandardOutPath</key>
        <string>/tmp/org.user.bindfs.sftpjail.out</string>
        <key>WatchPaths</key>
        <array>
                <string>/Volumes/BRIGHTRED</string>
        </array>
</dict>
</plist>

The WatchPath key is often required (it was in my case) to avoid timing problems. You may remove the keys StandardErrorPath/StandardOutPath and its strings after ensuring that everything works properly.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .