Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

For some reason, the launch daemon I created will not run successfully at system boot. I have tried it as a launch agent but that also doesn't work.

This is my plist located in /Library/LaunchDaemons:

<?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.inetmac4.status</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/Users/inetmac4/script/VMSTATUS/vmstatus_startup</string>
    </array>
    <key>KeepAlive</key>
    <false/>
</dict>
</plist>

Interestingly, the script does run correctly if executed manually, just not through the daemon. And when running launchctl list after boot, the status for com.inetmac4.status is 0, but the script didn't appear to ever run.

Any help would be greatly appreciated! I've Googled but none of the solutions out there that I've found will work for me.

EDIT: It should be noted that I'm trying to run it on a Mac Pro on 10.8.5

EDIT2: And the script:

`#!/bin/bash
#cd /Users/inetmac4/
#python -m SimpleHTTPServer > ~/outfile 2> ~/errfile < /dev/null & disown
cd /Users/inetmac4/Script/VMSTATUS/
./VM.sh  > ~/outfile 2> ~/errfile < /dev/null & disown`

VM.sh:

#!/bin/sh

#  VM.sh
#  
#
#  Created by INETMac4 on 9/12/13.
#
COUNTER=0

while [  1 ]; do

    perl VM_STATUS.pl
    let COUNTER=COUNTER+1
    sleep 5
done

and VM_STATUS.pl:

#!/usr/bin/perl
use Data::Dumper;

#-- the same command in list context



    my @result = `prlctl list --all`;

    shift @result;
    open (VMSTATUS, '>/Users/inetmac4/Sites/index.html');
    open (USERLOG, '</Users/inetmac4/script/username_log.txt');

    my @user_log = <USERLOG>;
    my @user_log = reverse(@user_log); 
    my @user_status;

    my %hash = ();
    foreach (@user_log){

        my @values = split(/\\/), $_;

        my $computer_name = $values[1];

        if (exists($hash{ $computer_name }) == 0){
            $hash{ $computer_name } = 'true';
            push(@user_status, $_);
        }

    }

    my @user_status_formatted;
    # Replaces domain name with OS type
    foreach (@user_status){
        my @values = split(/\\/), $_;

        if ($values[1] =~ /PSSTEAM-W7VPC/){
            push(@user_status_formatted, $values[0] . '\\' . "Windows 7" . '\\' . $values[2]. '\\' . $values[3])
        }
        if ($values[1] =~ /PSSTEAM-W8VPC/){
            push(@user_status_formatted, $values[0] . '\\' . "Windows 8" . '\\' . $values[2]. '\\' . $values[3])
        }
        if ($values[1] =~ /PSSTEAM-XPVPC/){
            push(@user_status_formatted, $values[0] . '\\' . "Windows XP" . '\\'. $values[2]. '\\' . $values[3])
        }

    }
    #print Dumper %hash;

    #print @result;

    foreach (@result){

        my @columns = split(/\s+/), $_;
        my $name  = $columns[3]." ".$columns[4];
        print VMSTATUS "<b>Virtual Machine: </b>". '<a href="VM_Start_INETMAC4_Windows7.cgi">'.$name."</a></br>\n";
        print VMSTATUS "<b>STATUS:</b> ". $columns[1]."</br>\n";
        if ($name =~ 'Windows 8.1'){
            print VMSTATUS "</br>\n";
        }
        foreach (@user_status_formatted){
            my @values = split(/\\/), $_;

            if ($values[0] =~ 'LOGGEDOUT' && $values[1] =~ $name){
                print VMSTATUS "<b>User:</b> Loggedout/ No user"."\n</br></br>";
                last;
            }
            if ($values[1] =~ $name){
                print VMSTATUS "<b>User: </b>  " . $values[2] . "\\" . $values[3]."\n</br></br>";
            }

        }
        print VMSTATUS "<hr>";
    }

    close (VMSTATUS);
share|improve this question
    
What is in vmstatus_startup? does it fork? –  Mark Oct 4 '13 at 18:56
    
Edited original with script @Mark it's supposed to call a shell script that refreshes the status of installed virtual machines and posts them to an html file. It works just by calling the executable in a terminal window though... Thanks! –  Tyler Oct 4 '13 at 19:01
    
Can you put that in the question and make it readable –  Mark Oct 4 '13 at 19:02
    
No problem, didn't realize how poorly it would format. –  Tyler Oct 4 '13 at 19:04
    
We need to see VM.sh as this is what should be in the .plish - all the pipes etc should be done in the .plist and not a shell script. Also disown I don't think should not used in a Launch Agent –  Mark Oct 4 '13 at 19:09
show 5 more comments

2 Answers

up vote 2 down vote accepted

For those who don't want to read through the comments, it was a pretty simple fix after Mark gave me a bit of insight.

Initially, I wrote the vmstatus_startup script to call VM.sh which would then continually refresh the perl script (every 5 seconds). I was attempting to call the shell script from launchctl which just adds layers of complexity.

Instead, calling the perl script directly from the .plist and giving the keep alive key allowed it to run constantly after boot.

Finally, I had to make sure to add the perl directory to the .plist above the location of the script since launchd doens't have a PATH the same way a user does.

share|improve this answer
add comment

You need to add <key>RunAtLoad</key><true/> to run the program when the job is loaded (or at login). See man launchd.plist:

RunAtLoad <boolean>
This optional key is used to control whether your job is launched once at
the time the job is loaded. The default is false.

If you want the program to be ran again if it terminates, also set KeepAlive to true.

You can apply changes to a plist by unloading and loading it.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.