shell command fails when running from crontab - macos

[Edit: the original title of this question was "Applescript running from crontab not accessing network?" but having found that the problem is about PATHs--not networking, or for that matter Applescript--I have tried to make it more searchable.]
I have a script which I would like to run at 9pm every night that will give me an alert if the Raspberry Pi in my basement is not responding. The script works fine, and tells me my device is up when I run it by hand:
osascript /users/nat/Code/applescript/ping-pi.scpt
It also runs from my crontab, but it tells me my device is down... which it isn't.
Here is the crontab line that worked a few minutes ago (for testing, not for 9pm):
14 15 * * * osascript /users/nat/Code/applescript/ping-pi.scpt
Here is the script:
--based on https://discussions.apple.com/thread/3833490
try
set ping to (do shell script "ping -c 2 <ddns site name here>")
display dialog "<ddns site name here> is up and running!" with icon note buttons {"OK"} default button 1
on error
-- if we get here, the ping failed
display dialog "<ddns site name here> is not responding" with icon caution buttons {"OK"} default button 1
end try
The only thing I can think of is that maybe I need to run it as root, but I don't know why that would be.
I can probably get rid of the "set ping to," but I'm just adapting code I found.

It turned out that this was not a network-access issue at all, but a PATH issue. I learned in this post that the default path for cron jobs includes just /bin and /usr/bin. which ping told me that I needed /sbin/ping, and when I edited the script accordingly, it worked.
I would imagine that this would cause many cron tasks to fail, so I'm a little surprised that it didn't come to my attention sooner.
As I mentioned above, there is no problem putting up a dialog from a cron job, and I will try removing the extra permissions I added, because I'm guessing I don't actually need any special network permissions.

Related

Cronjob Python3 Mac not executing

I just cannot get the cronjob on my Mac to execute. I have following cronjob line:
30 05 * * 1-5 usr/bin/python3 /Users/MyMac/Desktop/hello_world.py
Which should write helloworld to a txt file. This works perfectly when executing directly from the terminal. I insert this line into the crontab file using env EDITOR=nano crontab -e, exit, it says crontab: installing new crontab and when viewing the crontabs with crontab -l it's all there. It just doesn't execute when the time comes. What am I doing wrong?
I had the same issue as you, as I commented in your original post, but now I've solved it.
Python3 isn't actually located in usr/bin/Python3, which is why you don't get it to work. The terminal doesn't run the same environmental variables as crontab does which means that even if your path to python3 is wrong it will still manage to run the script from terminal since your user profile has the correct environmental variables set already. The crontab does not have these variables so it locates your script, tries to run it but can't find python3 thus not being able to compile and run the script. Python3 is located in /usr/local/bin/python3.
30 05 * * 1-5 /usr/local/bin/python3 /Users/MyMac/Desktop/hello_world.py
Try this, this works for me. I also recommend testing a software called CronniX. It let's you edit your crontab files without using the terminal which helps a ton. You can also test the script instantly from the software making it easier to see if it works or not (if it works the script should run instantly no matter what schedule times are set for it).
I also had the same problem, one of the errors for which my crontab did not work was the path of python3
in my case the path was this: /Library/Frameworks/Python.framework/Versions/3.6/bin/python3
30 10 * * 6 /Library/Frameworks/Python.framework/Versions/3.6/bin/python3 /Users/myMac/Desktop/main.py
Another problem for which it does not work was the permissions, to give all the permissions to cron you must do this:
Go to system preferences, security & privacy, full disk access
See the image here
Add a new one See the image here
Go to the folder pressing "Command + shift + G" and paste
this "/usr/sbin/cron", search cron and click open. Remember to check cron See the image here
If this doesn't work try giving accessibility permissions:
Go to system preferences, security & privacy,
accessibility
See the image here
Add a new one See the image here
Go to the folder pressing "Command + shift + G" and paste
this "/usr/sbin/cron", search cron and click open. Remember to check cron See the image here
Try this, this worked for me, also remember to give permissions to your terminal.

Mute Macbook pro when computer is shutting down

I'm thinking of using the Mac's applescript to make a program that mutes the system when it is shutting down.
Though I'm new to applescript and I don't know how to use the IF-statement to determine if the system is shutting down. I've done some googling and I've found that the finder app is the app that is "controlling" the shutdown, but i don't know how to check if the state is "shut down". Can anybody assist me in this matter?
AppleScript has no direct mechanism for detecting a shutdown/logout.
It does have a mechanism for creating applications that can react to themselves being quit.
Thus, you can:
use AppleScript to create a stay-open application (.app bundle) with a standard on quit handler, in which you perform the desired action (
make sure that the application is launched on login - in the simpler case as a Login Item (via System Preferences, see below), or, with more flexibility but complexity, as a launch agent (see https://stackoverflow.com/a/22872222/45375).
Instructions:
Open Script Editor and open a new script window.
Paste the following code:
# This standard handler is called when the application quits.
on quit
# Mute the system volume.
# !! See caveat below.
set volume with output muted
continue quit # signal to the system that it's OK to quit
end quit
Save the script as a stay-open application:
with File Format Application
check Stay open after run handler
Open System Preferences > Users & Groups > Login Items, drag the newly saved *.app bundle into the list, and check the checkbox next to it, so as to make it launch hidden.
The final step is to hide the new application's Dock icon, as there's no reason for it to have one:
From Terminal, run the following:
defaults write /full/path/to/newApp.app/Contents/Info.plist LSUIElement 1
Note: You could use LSBackgroundOnly too, but the advantage of LSUIElement is that you can still display UI elements if you want to, such as for debugging.
Important: Substitute the full path of your new app for /full/path/to/newApp.app; the command will only work if you specify the full path to the Info.plist file.
To test, start the new app interactively, and make sure that no Dock icon appears. (You can quit the app via Activity Monitor).
CAVEAT: If the intent is to suppress the system startup sound, set volume with output muted has two drawbacks:
it will not work if headphones happened to be plugged at the time of shutdown
you will have to unmute the volume on startup (however, you could do that in an on on run handler in the same app).
Consider the alternative approach below, which requires admin privileges to set up and invokes nvram SystemAudioVolume=%80 with root privileges, which bypasses the above drawbacks.
You could run do shell script "nvram SystemAudioVolume=%80" user name "someAdminUsername" password "matchingAdminPassword" with administrator privileges from the above AppleScript app, but you'd have to hard-code the password, which is not advisable for security reasons.
Alternative approach, using a system-wide logout hook via com.apple.loginwindow.
There's a deprecated mechanism for running a script on logout that, however, still works as of OSX 10.10; given that there's no direct non-deprecated equivalent, it may continue to be supported.
Note that you do need admin privileges:
sudo defaults write com.apple.loginwindow LogoutHook <yourScript>
<yourScript> must be an executable, such as a shell script; note that the executable is run in the context of the root user.
In case you're thinking of muting the startup sound, invoke the following shell command from that script:
nvram SystemAudioVolume=%80 # to try this interactively, prepend `sudo `
This will mute sounds until after a reboot, effectively muting the startup sound, without keeping the sound muted.
Note that the nvram command requires root privileges, which are by definition in effect in a script run via the com.apple.loginwindow logout hook.; by contrast, to try the command interactively, use sudo nvram SystemAudioVolume=%80 - otherwise, you'll get the following, unhelpful error message: nvram: Error setting variable - 'SystemAudioVolume': (iokit/common) general error
Honestly, it is better to make a deterministic solution. What I mean is, is that you make a script that:
Mutes your computer.
Shuts it down.
Then you take your script and create an Automator service, that you can assign to some shortcut, to make it easier for you to use it. ctrl-opt-cmd-eject or something. :)
This is just how I would have solved it, if I have the need, it is short and sweet to make work, and should work reasonably well.
If you want to use the LogoutHook mentioned in #mklement0's answer.
You can use the normal Applescript command set volume with output muted.
You just need to add the osascript shebang to the top of the Applescript document
i.e
#!/usr/bin/osascript
set volume with output muted
And then save the file as applescript text file.
In the save dialogue use : file format: Text )
It will get the extension .applescript
Once it is saved, use Terminal.app to chmod the script as you would a normal shell script which in effect it is.
i.e
/bin/chmod +x foo.applescript
Then add it to the loginwindows LogoutHook.
sudo defaults write com.apple.loginwindow LogoutHook foo.applescript
I Know this is an old post but for anyone still looking how to do this(like I was) I have a simple method.
Before I started Scripting I created a new folder in my home folder called toolbar scripts.(this is optional)
With the desktop showing Finder click on Go >Utilities >Script Editor.
In the window that opens type in or copy and paste the code
set volume with output muted
tell application "finder"
shut down
end tell
Click on the last button above the script you added - it should be compile. If you cannot find that button then on the top click on Script >Compile
Click on File >Save in the save as I called mine shutdown and chose the script folder (this is optional)
Down the bottom of the dialog box at file format click on the arrow and change the format to application and click on save.
Open the folder you saved it in and drag the icon to the dock. Click on the icon you just put in the dock.
now if all is right this should mute the volume and shutdown the computer.
This will not shutdown the computer if you still have anything open.
Cheers
Peter
first, you should create a sound-off script (with terminal)
sudo nano /Library/Scripts/sound-off.sh
after filling it with these lines:
#!/bin/bash
osascript -e ‘set volume output muted 1’
and make a sound-on script like that
sudo nano /Library/Scripts/sound-on.sh
and fill it with:
#!/bin/bash
osascript -e ‘set volume 4’
then access them as executing files
sudo chmod u+x /Library/Scripts/sound-off.sh
sudo chmod u+x /Library/Scripts/sound-on.sh
and the last part is set them when the mac device is turn off and on:
sudo defaults write com.apple.loginwindow LogoutHook /Library/Scripts/sound-off.sh
sudo defaults write com.apple.loginwindow LoginHook /Library/Scripts/sound-on.sh

Run .bat file as Administrator, get old version?

This is just bizarre. I've got a .bat file that I run using Windows 7's scheduler, and I noticed after I made an update to it, that it was still acting as though it were running the old version of the .bat program.
It's easy to tell which one ran - they output to a .txt file, and the new version dumps a lot more information. So here's what happens under three scenarios:
Open a cmd window (with right-click and "Run As Administrator"). CD to the directory and execute setvispw.bat in the usual way, by typing "setvispw.bat" and hitting Enter.
Result: current version runs as expected.
Right-click setvispw.bat and "Open"
Result: current version runs as expected. But that's not good, because I'm changing another user's password and need Admin privileges.
Right-click setvispw.bat and "Run As Administrator".
Result: something else runs! It looks like it's running the version from before I made changes to the .bat just a few days ago.
So I tried something even more strange. I replaced my functional program with a dummy program... and it was running the dummy program.
Finally, I added some "pause" statements... and that's when I got the answer. Rather than discard this bit of troubleshooting, I'll use the "Answer your own darned question" feature.
It turns out the problem was that I was depending on the output to setvispw.bat to tell me what version of the program had run. Well, both the old and new versions had this line:
echo Random string is !_RndAlphaNum! > C:\pathname\curVisitorPW.txt
But my added line was like this:
echo Sending email: >> curVisitorPW.txt
When I ran from C:\pathname, either in a CMD window or without Admin privileges, it worked just fine. But when I ran with Admin privs, like it does from the Scheduler, the working directory isn't C:\pathname - it's C:\Windows\System32. I didn't see that until I added the "pause" and saw that I wasn't running where I expeted! Sure enough, there's a curVisitorPW.txt sitting there in System32.
The solution, of course, was simple - use the fully qualified pathname.
Hopefully this will come in handy if someone like me is seeing bizarre behavior in a .bat file, and starts wondering if there's some sort of caching, or admin permissions/privileges, or something else crazy. I was ready to pin it on gremlins, myself.

mac osx cant find cronjob which opens safari every few seconds

I´ve installed a cronjob under mac osx which opens/curl an URL. Everything works fine but now I deleted all cronjobs by
crontab -r
and I deleted all lines in the crontab and
crontab -l
does not deliver any entry. The problem is that safari still opens every few seconds. Its also blocks my reboot command. I have to shut it down manually then I can restart my mac. When I get my login screen where I can click my User-Button the mac does a short "flash". So the screen gets white for one short moment. Looks like if you do an screenshot on an Iphone. Safari opens itself on startup (There is no entry in the startupitem list) to execute the Url. Somehow it feels as if there is a cronjob running in the backround but I cannot find it! Thanks.
Try running this script to see if you can spot the curl process being run, then you can find its Parent Process Id (PPID) in column 3, and then see the PID of the calling process. That will tell you how it is getting launched - or by whom, at least.
while :; do ps -aef | egrep "UID|curl" ; sleep 1; done
Ok, I found a solution. I had a .plist in /Library/LaunchAgents calling my URL. I deleted it, remove from trash and restared computer. No it´s gone. Yes.

Run a batch file with Windows task scheduler

I have a batch file daily.bat, this is the code:
cd C:\inetpub\wwwroot\infoweb\factuur\cron
c:\PHP\php.exe -f ./cron_pdf.php
ftp -s:ftp_upload.txt ftp.site.be
And I created a task with task scheduler in Windows 7. When I run the batch manually, everything goes fine, but when I try to run it with the task scheduler nothing happens.
My action is
'run script' "C:\inetpub\wwwroot\site\x\cron\daily.bat"
UAC is off and I am Admin.
Any idea why this is not working?
I faced the same problem, but I found another solution without having to modify my batch script.
The only thing that I missed out is at the 'Action' settings - "Start in (Optional)" option.
Go the task properties --> Action tab --> Edit --> Fill up as below:
Action: Start a program
Program/script: path to your batch script e.g. C:\Users\beruk\bodo.bat
Add arguments (optional): <if necessary - depending on your script>
Start in (optional): Put the full path to your batch script location e.g. C:\Users\beruk\(Do not put quotes around Start In)
Then Click OK
It works for me. Good Luck!
None of the above method worked. I tried it this way as said it in a tutorial and it worked.
Action:
Start a program
Program/script:
cmd
Add arguments:
/c start "" "E:\Django-1.4.1\setup.bat"
Worked for me on Win7 Pro. You must have an account with a password (blank passwords are no good)
For those whose bat files are still not working in Windows 8 and 10+ Task Scheduler , one thing I would like to add to Ghazi's answer - after much suffering:
Under Actions, Choose "Create BASIC task", not "Create Task"
That did it for me, plus the other issues not to forget:
Use quotes, if you need to, in your Start a program > program/script entry i.e "C:\my scripts\runme.bat" (or just use the Browse button)...
Use the Start In path to your batch file, even though it says optional - BUT DON'T use quotes in the Start In field. (Crazy but true!)
This worked without any need to trigger a command prompt. And it is the quickest and simplest method.
(Sorry my rep is too low to add my Basic Task tip to Ghazi's comments)
Make sure "Start In " has NO QUOTES.
It is working now. This is what I did. You probably won't need all these steps to make it work but just to be sure try them all:
Check the account parameters of your scheduled task and make sure they are set to run whether or not someone is logged into the machine
check run with most privileges/rights
Make sure you go to the full path first: cd C:\inetpub\wwwroot\infoweb\factuur\cron
Don't use double quotes in your batch files (don't know why but seems to help)
Be super admin, enter 'Net user administrator /active:yes' in command prompt, log out and log in as the super admin, so UAC is off
Make sure "Start In" does NOT end with a BACKSLASH.
My script was to pull latest code from master and publish a new branch
cd D:\dev\repo
git checkout master
git pull
git branch -D my-branch
git push origin --delete my-branch
git checkout -b my-branch
git push -u origin my-branch
exit
Had an issue where my task was not firing simply because it was running on a laptop without a power cord... Under the conditions tab, by default it is checked so that a task will not run while AC power is not connected.
Under Windows7 Pro, I found that Arun's solution worked for me: I could get this to work even with "no user logged on", I did choose use highest priveledges.
From past experience, you must have an account with a password (blank passwords are no good), and if the program doesn't prompt you for the password when you finish the wizard, go back in and edit something till it does!
This is the method in case its not clear which worked
Action: start a program
Program/script : cmd
(doesn't need the .exe bit!)
Add arguments:
/c start "" "E:\Django-1.4.1\setup.bat"
I messed with this for several hours and tried many different suggestions.
I finally got it to work by doing the following:
Action: Start a program
Program/Script: C:\scriptdir\script.bat
Add arguments (optional) script.bat
Start in (optional): c:\scriptdir
run only when user logged in
run with highest privileges
configure for: Windows Vista, Windows Server 2008
If all of the rest fails for you here ensure that the user you are trying to run the task as has access to the file you're trying to use.
In my case I was trying to run a batch file from C:\Users\Administrator\Desktop which the account couldn't access. Moving it to a neutral location on C:\ resolved the issue.
I post the answer to this question here and here.
Using the Run button in the Task Scheduler main window to test several variations finally found the correct settings. This two options must be combined:
-Run only when user is logged on
-Run with highest privileges.
All other variations failed. It's infuriating all the time wasted on this, but at least it works.
OS: WINDOWS 8 CORE (BASIC) VERSION
Please check which user account you use to execute our task. It may happen that you run your task with different user then your default user, and this user requires some extra privileges.
Also it may happen that the task is executed but you cant see any effect because the batch file waits for some user response so please check task manager if you see your process running.
Once it happen that I schedule a batch with svn update of some web page and the process hangs because svn asked for accepting server certificate.
Don't use double quotes in your cmd/batch file
Make sure you go to the full path start in (optional):
C:\Necessary_file\Reqular_task\QDE\cmd_practice\
Try run the task with high privileges.
put a \ at the end of path in "start in folder" such as c:\temp\
I do not know why , but this works for me sometimes.
Action: Start a Program
Program/script: C:\Windows\System32\cmd.exe
Add arguments: /k start "" "E:\scripts\example.bat"
Add exit to the end of your batch file.
The cmd window will not show if you select Run whether user is logged in or not. You need to select Run only when user is logged on to see the window in action.

Resources