I have been setting up a launch daemon that launch a bash script on demand. However, once I load my launch agent and communicate via socket, then it keep running my bash script every 10 seconds.I've even set KeepAlive flag as false in plist and added delay in bash script, but still it keep running.
How can I set it up to run only once when i connect with the socket.
Plist file:
<?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.example.test.helper</string>
<key>Program</key>
<string>/Library/Application Support/test/testexec</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Application Support/test/testexec</string>
</array>
<key>OnDemand</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>Sockets</key>
<dict>
<key>MasterSocket</key>
<dict>
<key>SockFamily</key>
<string>Unix</string>
<key>SockPathMode</key>
<integer>438</integer>
<key>SockPathName</key>
<string>/var/run/com.example.test.helper.socket</string>
<key>SockType</key>
<string>Stream</string>
</dict>
</dict>
</dict>
</plist>
bash script file:
#!/bin/bash
FILE_PATH="/var/log/test.log"
print()
{
echo "$(date +"%m-%d %T") $1" >> $FILE_PATH
}
/bin/rm -r "/private/var/test"
retcode=$?
print "rm returncode: $retcode"
if [ $retcode -ne 0 ];
then
print "The removing failed"
fi
sleep 15
The "on demand" key was used in Mac OS X 10.4 Tiger to control whether a job was kept alive or not. The key should not be used anymore.
With the keepalive key set to false, the default is to start a job only on demand.
Related
I have a launch agent that runs a bash script whenever a usb device is connected. I want it to run just once, but when i connect the device, the script keeps running every 10 seconds.
Here is the plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.program</string>
<key>Program</key>
<string>/Users/Peter/Desktop/test1.sh</string>
<key>LaunchEvents</key>
<dict>
<key>com.apple.iokit.matching</key>
<dict>
<key>com.apple.device-attach</key>
<dict>
<key>idProduct</key>
<integer>1476</integer>
<key>idVendor</key>
<integer>1356</integer>
<key>IOProviderClass</key>
<string>IOUSBDevice</string>
<key>IOMatchLaunchStream</key>
<true/>
</dict>
</dict>
</dict>
</dict>
</plist>
Here is the script:
#!/bin/bash
open -a "Spotify";
sleep 11;
I added sleep 11, as I read that the script needs to run at least 10 seconds to let launchd think its done its task. This however doesn't help any.
In terminal running launchctl list com.example.program gives:
"LimitLoadToSessionType" = "Aqua";
"Label" = "com.example.program";
"TimeOut" = 30;
"OnDemand" = true;
"LastExitStatus" = 0;
"Program" = "/Users/Peter/Desktop/test1.sh";
By default, launchd starts programs when their launch conditions are met, and then restarts them if they exit or crash. To keep it from relaunching your script, just add <key>KeepAlive</key><false/> to your .plist (and then unload and reload it). It might also be necessary to add <key>AbandonProcessGroup</key><true/> to keep launchd from killing the "leftover" Spotify process (though I think it'll work without this).
I was looking for an answer to my question on stackoverflow and found a thread (https://superuser.com/questions/229773/run-command-on-startup-login-mac-os-x). That's how I found out about launchd.plist and I made one by myself:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>js.leapmotion</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>open</string>
<string>/Applications/Utilities/Terminal.app</string>
</array>
<key>LaunchOnlyOnce</key>
<true/>
</dict>
</plist>
this indeed starts my terminal after booting my mac. But now I want it to navigate to a directory and run the command gulp in there.
This again will do the rest, opens up a localhost and so on...
So in the end I just need to run gulp within an specific directory. That's all. If launchd.plist is not the best way to go, then I'm open for alternatives.
Otherwise I would like to know how I can tell the terminal what commands it should run.
Thanks for hints.
cheers
J
You can use the open command to open Terminal and run a script by using the -a flag. For example, open -a Terminal /path/to/myscript will open a new Terminal window and run myscript. Note that when myscript finishes, the session will terminate (i.e. there's no shell). To change that, you can run bash or whatever your preferred shell is as part of the script.
In your case, I would suggest creating a basic script to do whatever you want Terminal to execute, such as :
#!/usr/bin/env bash
cd /path/to/your/directory
/usr/bin/gulp
Save that (making sure it's executable), and then change your launchd plist to match:
<key>ProgramArguments</key>
<array>
<string>open</string>
<string>-a</string>
<string>Terminal</string>
<string>/path/to/yourscript</string>
</array>
I've made a script that each day it gets the local time, and then makes an alias of a folder specified by me through code on the desktop. At the beginning, it asks for what day it is (via a list). It doesn't work because even if I use launchd to run it every 5 minutes, it will ask me for the list. Is there a way to get the variable stored every day, and then just make it do the rest of the work throughout the day?
I've actually combined AppleScript and Automator to make it function, so I need to make the Automator run and not the AppleScript.
My PLIST Code
<?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>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>wallpaper.restart</string>
<key>ProgramArguments</key>
<array>
<string>PATH:TO:FILE</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>1</integer>
</dict>
</dict>
</plist>
I would appreciate any pointers for me to get started, or anything that could help.
Thanks
To run a script at some interval, you'd use a .plist that looks something 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>com.mycompany.myScript</string>
<key>Program</key>
<string>/Applications/myScript/myScript.app/Contents/MacOS/applet</string>
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>1</integer>
<key>StartInterval</key>
<integer>600</integer>
</dict>
</plist>
Change the 600 to whatever number of seconds you'd like it to run at, for example 300 for every 5 minutes.
To write data to a .plist file so you can access it at any time, you would use something like this...
do shell script "defaults write com.mycompany.myApp MyInfo '" & theInfo & "'"
To then read the information you'd use code like this...
set myPref to do shell script "defaults read com.mycompany.myApp MyInfo"
Lastly, I'm not sure you need a "list", you can get the date using a script similar to this...
do shell script "date \"+%Y-%m-%d\""
The format that I've chosen in this example is 2016-06-01, but you can change the format information to whatever you'd like by changing the string after the date command. See the manual page for date for more information or look here.
Using Applescript how can I register a login item for all users?
I understand that there is a library/preferences/loginwindow.plist file which holds this information.
I need to launch safari on log in and navigate to a URL. This needs to be done for any user that logs in. I've been looking to Launch Agents and this seems like my best bet.
I have the following in Library/LaunchAgents/ which is launching safari at log in but I don't know how to specifiy the URL
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>heymega.safari.launcher</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/Applications/Safari.app/Contents/MacOS/Safari</string>
</array>
</dict>
</plist>
You should be able to include the url as an argument:
<string>/Applications/Safari.app/Contents/MacOS/Safari</string>
<string>http://example.com</string>
If that doesn't work you could try calling osascript to direct Safari to the url:
/Applications/Safari.app/Contents/MacOS/Safari & sleep 1 && osascript -e 'tell application "Safari" to open location "http://www.example.com"'
The osascript method uses sleep so that Safari has a chance to launch before executing.
I know when using a plist in the launch daemons folder there is a key called <StartInterval>. I much prefer using launchctl when I can because it is a lot quicker then writing out a whole plist, but I have not been able to figure out how to get the process to restart after it has been killed. I have already read the man page and haven't found anything there. Is there a way? Typically I use the following command:
launchctl submit -l somename -p /path/to/script -o output.txt -e errors.txt
But that will not restart the program if it is killed after any time interval.
launchctl submit should already run the program again if it terminates for some reason:
submit -l label [-p executable] [-o path] [-e path] -- command [args]
A simple way of submitting a program to run without a configura-
tion file. This mechanism also tells launchd to keep the program
alive in the event of failure.
-l label
What unique label to assign this job to launchd.
-p program
What program to really execute, regardless of what fol-
lows the -- in the submit sub-command.
-o path Where to send the stdout of the program.
-e path Where to send the stderr of the program.
To run a program again if it exits with an error, set the SuccessfulExit criteria for KeepAlive to false:
<?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>test</string>
<key>ProgramArguments</key>
<array>
<string>bash</string>
<string>-c</string>
<string>n=$((RANDOM%2));say $n;exit $n</string>
</array>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>StartInterval</key>
<integer>60</integer>
</dict>
</plist>
launchd throttles jobs so it takes about 10 seconds for the program to respawn.