run once and then vaporize

View: New views
4 Messages — Rating Filter:   Alert me  

run once and then vaporize

by Blake Garner :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm hoping that an elegant solution exists for launchd to kick off a
script on boot as root and then unload and remove itself. I understand
that login hooks and startup items may be simpler but I would prefer
to use a launchd plist as it fits better with our automation system.

This is what I have right now..

<?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>runonce</string>
        <key>ProgramArguments</key>
        <array>
                <string>/Library/Scripts/runonce.sh</string>
                <string>;</string>
                <string>/bin/launchctl</string>
                <string>unload</string>
                <string>-w</string>
                <string>/Library/LaunchDaemons/runonce.plist</string>
                <string>;</string>
                <string>/usr/bin/rm</string>
                <string>/Library/LaunchDaemons/runonce.plist</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
</dict>
</plist>

My test script currently just echo's some text into system.log and
exits. The script runs but the launchd item fails to unload or remove
itself. Ideally I would like to keep the removal function in the
launchd item.

Suggestions and links to similar examples are welcome.

Thanks,
Blake
_______________________________________________
launchd-dev mailing list
launchd-dev@...
http://lists.macosforge.org/mailman/listinfo.cgi/launchd-dev

Re: run once and then vaporize

by Quinn-9 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

At 19:15 -0700 23/7/08, Blake Garner wrote:
>My test script currently just echo's some text into system.log and
>exits. The script runs but the launchd item fails to unload or remove
>itself.

That's because launchd does not pass the ProgramArguments to a shell;
rather, it invokes fork/exec (maybe even posix_spawn these days) with
those arguments.  So the ";" isn't considered special.  If you modify
your "runonce.sh" to print all of its arguments, you'll find that
it's getting a whole bunch of extra ones (-:

I don't think this ProgramArguments approach is going to work.  You
will have to unload the job from your script.

Alternatively, don't unload the job.  Once a job is loaded, it
doesn't depend on the plist file, so removing the plist file out from
underneath launchd won't cause you any problems.  The job will
continue to exist in launchd (until the system restarts) but it won't
get run against unless someone specifically invokes it.

S+E
--
Quinn "The Eskimo!"                    <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
_______________________________________________
launchd-dev mailing list
launchd-dev@...
http://lists.macosforge.org/mailman/listinfo.cgi/launchd-dev

Re: run once and then vaporize

by James Bucanek :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Blake Garner <mailto:trodemaster@...> wrote (Wednesday,
July 23, 2008 7:15 PM -0700):

>I'm hoping that an elegant solution exists for launchd to kick off a
>script on boot as root and then unload and remove itself. I understand
>that login hooks and startup items may be simpler but I would prefer
>to use a launchd plist as it fits better with our automation system.
>
>This is what I have right now..
>
><?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>runonce</string>
><key>ProgramArguments</key>
><array>
><string>/Library/Scripts/runonce.sh</string>
><string>;</string>
><string>/bin/launchctl</string>
><string>unload</string>
><string>-w</string>
><string>/Library/LaunchDaemons/runonce.plist</string>
><string>;</string>
><string>/usr/bin/rm</string>
><string>/Library/LaunchDaemons/runonce.plist</string>
></array>
><key>RunAtLoad</key>
><true/>
></dict>
></plist>
>
>My test script currently just echo's some text into system.log and
>exits. The script runs but the launchd item fails to unload or remove
>itself. Ideally I would like to keep the removal function in the
>launchd item.

The elements of the ProgramArguments key are the arguments
passed to your script. There is no shell or scripting language
involved. Your script was simply passed the literal arguments

     runonce.sh ';' '/bin/launchctl' unload -w
'/Library/LaunchDaemons/runonce.plist' ';' ...

As the documentation for ProgramArguments says: Please read
execvp(3) very carefully!

Unless runonce.sh takes the remainder of its command line
arguments and passes them to a shell for execution, nothing else
will happen.

If you want your daemon to uninstall itself after running, it
will need to do that itself.

--
James Bucanek

_______________________________________________
launchd-dev mailing list
launchd-dev@...
http://lists.macosforge.org/mailman/listinfo.cgi/launchd-dev

Parent Message unknown Re: run once and then vaporize

by Blake Garner :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks Quinn!

Your explanation was informative and solved my problem. I attempted to
have the script remove the .plist before but It was failing due to
permission problems. After correcting the permissions on my script
it's working!

blake

On Thu, Jul 24, 2008 at 7:43 AM, Quinn <eskimo1@...> wrote:

> At 19:15 -0700 23/7/08, Blake Garner wrote:
>>My test script currently just echo's some text into system.log and
>>exits. The script runs but the launchd item fails to unload or remove
>>itself.
>
> That's because launchd does not pass the ProgramArguments to a shell;
> rather, it invokes fork/exec (maybe even posix_spawn these days) with
> those arguments.  So the ";" isn't considered special.  If you modify
> your "runonce.sh" to print all of its arguments, you'll find that
> it's getting a whole bunch of extra ones (-:
>
> I don't think this ProgramArguments approach is going to work.  You
> will have to unload the job from your script.
>
> Alternatively, don't unload the job.  Once a job is loaded, it
> doesn't depend on the plist file, so removing the plist file out from
> underneath launchd won't cause you any problems.  The job will
> continue to exist in launchd (until the system restarts) but it won't
> get run against unless someone specifically invokes it.
>
> S+E
> --
> Quinn "The Eskimo!"                    <http://www.apple.com/developer/>
> Apple Developer Relations, Developer Technical Support, Core OS/Hardware
> _______________________________________________
> launchd-dev mailing list
> launchd-dev@...
> http://lists.macosforge.org/mailman/listinfo.cgi/launchd-dev
>
_______________________________________________
launchd-dev mailing list
launchd-dev@...
http://lists.macosforge.org/mailman/listinfo.cgi/launchd-dev