Launchd no ejecutará un comando bindfs

Quiero usar launchd para ejecutar comandos bindfs al iniciar sesión, como root. Tengo un plist en /Library/LaunchAgents/loginsftpjailmount.plist (con chmod 600) y un script de shell en /usr/local/bin/loginsftpjailmount.sh.

Debería comenzar diciendo que funciona, si cambio el script bash para que se ejecute

mkdir /Users/Me/Desktop/itworks

luego crea con éxito el directorio "itworks", tanto al iniciar sesión como al ejecutar

sudo launchctl load /Library/launchAgents/loginsftpjailmount.plist

Y la carpeta creada es propiedad de root y tengo que escribir mi contraseña para eliminarla. Cuando ejecuto manualmente el script bash desde la terminal usando sudo, el comando bindfs funciona.

Entonces, para resumir, sé que el guión funciona. Sé que el plist funciona. Sé que trabajan junto con launchd. ¡Pero el comando bindfs no se ejecuta! Revisé el registro del sistema con

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

y dice que sale con el error 127 (com.user es parte de la etiqueta de mi plist). Busqué en línea y ninguna de las soluciones para el error 127 me funciona. Como referencia, dos plists que he usado son:

<?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/>

y también

<?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>
Encontré mi propia respuesta. El problema es que bindfs está instalado en /opt/local/bin y launchd no puede encontrarlo. Entonces, simplemente cambiando mi script de shell para ejecutar la ruta completa, se ejecuta. Mi script de shell ahora es como "/opt/local/bin/bindfs directorio1 directorio2" en lugar de simplemente "bindfs directorio1 directorio2". Pero tengo un nuevo problema: se ejecuta cuando sudo carga manualmente, pero no se ejecuta al iniciar sesión.

Respuestas (1)

El proceso bindfs debe iniciarse con privilegios de root. Lanzarlo como agente evitaría esto.

Entonces sudo launchctl unload ..., y sudo launchctl remove ...(el subcomando remove elimina el agente de la base de datos launchd - ¡el archivo no se eliminará!) el plist, mueva el plist a /Library/LaunchDaemons/ y vuelva a cargarlo con sudo launchctl load ....

Un org.user.bindfs.sftpjail.plist correctamente nombrado y compuesto se vería así:

<?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>

A menudo se requiere la clave WatchPath (lo fue en mi caso) para evitar problemas de sincronización. Puede eliminar las claves StandardErrorPath/StandardOutPath y sus cadenas después de asegurarse de que todo funciona correctamente.