![]() |
can't send email via script using launchd?
I'm trying to send an email via shell script. e.g. my shell script is something like this:
#!/bin/sh echo testing | mail -s 'this is a test' user@domain.com My launchdaemon runs the script: /usr/local/scripts/testscript.sh I *know* the script is working, because I added some debugging (I added a line: echo is this working and sure enough, "is this working" is showing up in the console) but the email part kicks off an error message about 30 seconds later: Stray process with PGID equal to this dead job: PID ### PPID 1 sendmail The script *works* when I run it with a cron job. But why wouldn't it work as a launchd item? And why is it I'm only having problems with the email segment of my scripts? I've tried other scripts and they all seem to work fine. |
What is the path to the plist?
What owner:group does it have? Post the plist. -HI- |
Here're the permissions:
-rw-r--r-- 1 root wheel 386 Sep 24 09:28 com.edw.test.plist The path is /Library/LaunchDaemons/com.edw.test.plist Here's the plist. If it makes any difference, I created it using Lingon. <?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.edw.test</string> <key>ProgramArguments</key> <array> <string>/usr/local/scripts/testscript.sh</string> </array> <key>StartInterval</key> <integer>1800</integer> </dict> |
Quote:
|
Quote:
(with owner:group = you:admin ... or you:you, whatever). Is the plist actually loading? i.e., does the job appear in the launchctl list? For the location you have now: sudo launchctl list |grep edw -- If you move it to ~/Library/LaunchAgents: launchctl list |grep edw Try force loading it: launchctl load -w ~/Library/LaunchAgents/com.edw.test.plist Or kickstarting it: launchctl start com.edw.test |
Quote:
|
re wrong user: sorry I didn't make it clear, I *want* the script to run as root.
And I tried another piece of debugging: I put in an "echo $(whoami)" statement in the script, and the console is showing "root", so it seems like it *is* running as root. So it appears the script *is* running, and it *is* running as root. But there seems to be some sort of problem specific to sending an email. Again, if I run the script using *cron*, it *works*. I'm just attempting to transfer my cron jobs over to launchd like a good Apple user. |
errr... what are the permissions on the file '/usr/local/scripts/testscript.sh'? I think you'd need it to be owned by root, and have the execute bits set, though there are better Unix people out there than me.
|
The script is owned by root and is executable. It *does* run, at least the non-email part of it runs. Here're the details in case I'm missing something:
-rwxr-xr-x 1 root wheel 286 Sep 23 22:20 testscript.sh |
odd. I think we need more context. why do you want this job to be run as root? generally speaking, the system launchdaemon folder is for very low-level jobs that need to be run out of sight (for reasons of security and system stability). normally I'd expect you to put user-created plists in the system launchagents folder, rather than the launchdaemons folder. what happens if you move it over there? and what are you trying to accomplish in the long term?
|
Well, basically the end goal is to run a script that checks the RAID on the machine via "diskutil checkraid" and to send an email alert if it detects a problem. I'm running it as root simply because I had problems running it as an admin. Yes, I'm aware of the security implications, but right now I'd be happy with something that simply works.
(Oh, and yes, I know that my script is supposed to send email *only* if it detects an error. For troubleshooting purposes, I've been forcing the email to send regardless of whether or not there's an error.) The script *works* when run as a cron job. The *exact same* script chokes when run as a launchd process. And in the troubleshooting process, I'm determining that for some reason, cron doesn't mind sending out email, but launchd balks. In fact, launchd balks at sending email even in such a simple script (see my first post). And again, cron has no problems. Cron is running the script as root, and as far as I can tell, launchd is also running the script as root. So that's the problem. Maybe it'd be better worded as: why does launchd not want to send email? |
And maybe I should also be asking, can anyone else replicate this problem? The machine in question is running OS X 10.5.5 server, but the problem has existed for all versions of 10.5.
|
ok, after a bit of poking around on the internet, and a bit of experimentation, I've gotten this to work correctly (from within my user account, mind you - there may still be issues involved with running it as a lower-level daemon).
add the following key (in red) to your plist: Code:
<?xml version="1.0" encoding="UTF-8"?> |
Hot damn, that worked! So bizarre, but great. Thank you!
|
The reason for the AbandonProcessGroup is explained in this Apple tech note:
http://developer.apple.com/technotes/tn2005/tn2083.html Quote:
|
Hayne, thanks for the link and info. I wonder if you'd be willing to explain a bit more about this issue.
I've got a similar script which I've been running via cron. I was thinking of modernizing and changing that to launchd. Am I correct in assuming that in the OP's case the child process is 'mail'? If so, how would he go about running mail via launchd as suggested by the technote you quoted? |
Quote:
now the problem in this case, I think, is that sendmail returns a completion value before it has actually finished sending the email, passing on that 'actually sending' part to some sub-process (probably to keep the system from being hung up while sendmail negotiates with remote hosts). this causes launchd to terminate the process and its spawned children (i.e. that process that's still trying to send the email). since sendmail is prewritten code, there's no way (that I know of) to extract out the sub-process that actually sends the email. you could try using the -I option (forcing mail into interactive mode), which might keep sendmail from returning a completion value too early, but that might generate different errors. really, the above technote is for people who are writing their own daemons, who can explicitly construct them as separate launchd items, or make sure they are properly detached from the parent process; for retroactive use with programs like sendmail the 'AbandonProcessGroup' key is probably the only choice available. |
An alternative might also be to just have the script sleep for a bit (say 30 seconds) so that the mail has completed before the script finally finishes.
But using the AbandonProcessGroup setting is cleaner. |
Please excuse my ignorance, but I'm a rank amateur when it comes to this stuff.
The OP's script uses the 'mail' command. I thought that all 'mail' did was compose the message as a file and write it to the mail drop box (/var/spool/postfix/maildrop). Launchd watches that directory and runs the postfix 'master' process when it detects a change. So, the 'mail' process in the script wouldn't be delayed by communicating with servers or whatever. Shouldn't it just return a completion code when the file is written and not spawn any daughter processes? |
Quote:
my guess would be that mail triggers the postfix master directly, rather than waiting for launchd to do it. that would make the pfm a child process of mail, rather than of launchd. but I can't seem to find any documentation of the inner workings of mail to confirm that. |
Quote:
|
Quote:
Quote:
which is defined in Libc-498/include/paths.h as: #define _PATH_SENDMAIL "/usr/sbin/sendmail" |
Hello,
I have the same problem, my script doesn't send e-mail as root with launchd !! I wrote this in my script but it didn't work. <key>AbandonProcessGroup</key> <true/> :( |
Quote:
|
Hello,
Well sorry for the mistake but I wrote it in the launchd plist file not in the script. Code:
<?xml version="1.0" encoding="UTF-8"?>Code:
#!/bin/shI make the plist file with lingon but it doesn't send e-mails. |
Launchd is for the birds
Quote:
Some of you Unix gurus out there may see some benefit in dumping cron for this obtuse and difficult scheduler, but the very fact that it is bloody difficult to schedule a simple "email me" script underscores the fact that something that used to be *really* simple is now a big PITA. That is not progress. This discussion is the ONLY place on the web that I was able to turn up the source of this problem. I see there is an Apple technote on it as well, but it should be in the launchd man page. Well, maybe it is, but I wouldn't know: myserver:~ admin$ man launchd No manual entry for launchd myserver:~ admin$ man launchctl No manual entry for launchctl Gee thanks, Apple. |
Everything is easier once you know how.
Quote:
Quote:
myserver:~ admin$ man launchd No manual entry for launchd myserver:~ admin$ man launchctl No manual entry for launchctl myserver:~ admin$ man launchd.plist launchd.plist(5) BSD File Formats Manual launchd.plist(5) NAME launchd.plist -- System wide and per-user daemon/agent configuration files DESCRIPTION This document details the parameters that can be given to an XML property list that can be loaded into launchd with launchctl. Dropping launchd into google brings the following link up: http://developer.apple.com/macosx/launchd.html Quote:
At least the unix layer is accessible. If it wasn't, this would all be moot. |
Quote:
sandboxd[49674] krb5kdc(73) deny mach-lookup com.apple.CoreServices.coreservicesd Here's the script This is only the portion, the other part does other stuff and is working, so it's not permission of the script): #!/bin/sh # email subject SUBJECT="test script got an error" # Email To ? EMAIL="abc@xxxyyyzzz.com" # Email text/message EMAILMESSAGE="/tmp/emailmessage.txt" echo "test script got an error" > $EMAILMESSAGE # send an email using /bin/mail /usr/bin/mail -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE Here is the plist, in /Library/LauchDaemons: -rw-r--r--@ 1 root wheel 509 Sep 29 17:00 com.humanworldwide.test.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.humanworldwide.test</string> <key>LowPriorityIO</key> <false/> <key>Program</key> <string>/Users/humanadmin/Desktop/scripts/test.sh</string> <key>StartCalendarInterval</key> <dict> <key>Hour</key> <integer>5</integer> <key>Minute</key> <integer>02</integer> </dict> </dict> </plist> |
I have the same problem, however only on Snow Leopard Server - not on Leopard Server. The AbandonProcessGroup key does seem to fix the problem, but why this should only happen on SL for me is a mystery.
|
I had the same problem and solved it with that solution and additionally adapting the postfix.plist (/System/Library/LaunchDaemons/org.postfix.master.plist):
Code:
<?xml version="1.0" encoding="UTF-8"?> |
| All times are GMT -5. The time now is 05:45 PM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.