I have a global launchd plist file that runs a backup script periodically. The script is a pretty simple bash script that sets up some variables and calls duply. However the plist doesn't seem to be preventing the system from going into sleep mode.
Is there a way of preventing the mac from going into sleep mode whilst this specific launchd plist and associated script are running?
The solution that seems to be working is
caffeinate -s [utility]
This forces the system to stay awake until the [utility] closes.
-s Create an assertion to prevent the system from sleeping. This assertion is valid only when sys-tem system
tem is running on AC power.
The full man page explains more.
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/caffeinate.8.html
I use the following to prevent my Mac sleeping:
pmset noidle
and then I use Ctrl-C to kill that and allow it to sleep again.
Related
I'm doing my project and I need to log keystrokes system wide in macOS. So, I turned over to GitHub and found Swift-Keylogger. The only problem is I can't quit the Terminal while the program is still running.
Is there any way to not to run this in terminal or closing the terminal window instead of creating a mac app like here.
Note: There are some mac app style executables in github but they are not providing the output I want and some need additional permissions.
Instead of running the executable like ./Keylogger use nohup ./Keylogger &.
You can quit the Terminal after executing the command.
To kill the Keylogger, run ps -e | grep "Keylogger" to get pid and kill -9 pid.
P.S. I thought of adding it as well as running at startup but I'm too lazy to update the repository.
Is there any way to run a script only at shutdown?
I mean, only when the computer is really shutting down to off state. This script should not run when doing just a log off or restart.
Few days ago I published on github a configuration/script able to be executed at boot/shutdown.
Basically on Mac OS X you could/should use a System wide and per-user daemon/agent configuration file (plist) in conjunction with a bash script file. This is a sample of the plist file you could use:
<?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>boot.shutdown.script.name</string>
<key>ProgramArguments</key>
<array>
<string>SCRIPT_PATH/boot-shutdown.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>LOG_PATH/boot-shutdown.log</string>
<key>StandardErrorPath</key>
<string>LOG_PATH/boot-shutdown.err</string>
</dict>
</plist>
You can place this file into /Library/LaunchDaemons. There are many directories where the plist file could be placed, it depends from what you need, the rights of the process and so on.
~/Library/LaunchAgents Per-user agents provided by the user.
/Library/LaunchAgents Per-user agents provided by the administrator.
/Library/LaunchDaemons System wide daemons provided by the administrator.
/System/Library/LaunchAgents Mac OS X Per-user agents.
/System/Library/LaunchDaemons Mac OS X System wide daemons.
This script boot-shutdown.sh will be loaded and executed at every boot/shutdown.
#!/bin/bash
function shutdown()
{
# INSERT HERE THE COMMAND YOU WANT EXECUTE AT SHUTDOWN OR SERVICE UNLOAD
exit 0
}
function startup()
{
# INSERT HERE THE COMMAND YOU WANT EXECUTE AT STARTUP OR SERVICE LOAD
tail -f /dev/null &
wait $!
}
trap shutdown SIGTERM
trap shutdown SIGKILL
startup;
Then call launchctl command which load and unload daemons/agents.
sudo launchctl load -w /Library/LaunchDaemons/boot-shutdown-script.plist
It looks like the most straightforward way would be to write a small C++ application that would run as a daemon with launchctl, catch the shutdown notification but ignore the reboot notification (see below) and then call whatever is given to it as arguments, e.g. a shell script. It does not look like Apple provides libraries to catch those notifications in any other language.
From the "Kernel Programming" manual https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KernelProgramming/KernelProgramming.pdf from Apple, page 150:
"Although OS X does not have traditional BSD-style shutdown hooks, the I/O Kit provides equivalent functionality in recent versions. Since the I/O Kit provides this functionality, you must call it from C++ code."
"To register for notification, you call registerSleepWakeInterest (described in IOKit/RootDomain.h) and register for sleep notification. If the system is about to be shut down, your handler is called with the message type kIOMessageSystemWillPowerOff. If the system is about to reboot, your handler gets the message type kIOMessageSystemWillRestart. If the system is about to reboot, your handler gets the message type kIOMessageSystemWillSleep."
As you can see there is a different message for reboot, so you can handle the shutdown case exclusively.
Here is a way that does work (I just tested it) but it is quite technical and not for inexperienced people... I put a wrapper around /sbin/shutdown. This will work even if you shutdown your Mac from the Apple menu in the GUI.
Basically, you need to su to root, like this, and rename the existing, Apple-supplied shutdown binary to shutdown.orig.
su -
cd /sbin
mv shutdown shutdown.orig
Then you create a bash script called shutdown that does what you want first, then execs the original Apple-supplied shutdown binary.
#!/bin/bash
Do something you want done before shutdown
exec /sbin/shutdown.orig "$#"
There are three things to watch out for...
1. Make all the permissions the same on shutdown as shutdown.orig
2. Parse the parameters to the originl shutdown and see if `-r` is one of them as this means it is a `restart` shutdown. You will also have to pass through the other parameters that Apple calls the script with - if any.
3. Apple may feel at liberty to overwrite your lovely, shiny, new `shutdown` script when updating OSX, so maybe abstract out the bulk of your personal shutdown script into another place so that you can easily re-insert a single-line call to it if/when Apple overwrites it at some point.
Be careful! And make a backup first!
https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CustomLogin.html#//apple_ref/doc/uid/10000172i-SW10-SW1
I tested it on my MacOs 12.5.1,It does work!
cat LogoutHook.sh
#!/bin/bash
export BLUEUTIL_ALLOW_ROOT=1
function shutdown()
{
echo `date` >> /Users/blanc/.LaunchShell/shutdown_date.log
echo `whoami` >> /Users/blanc/.LaunchShell/shutdown_date.log
/usr/local/bin/blueutil -p 0
sleep 1
#exit 0
}
shutdown;
sudo defaults write com.apple.loginwindow LogoutHook /Users/blanc/.LaunchShell/LogoutHook.sh
In case someone comes to this answer like me googling for similar but somewhat different problem.
Due to CopyQ crash bug that I found https://github.com/hluk/CopyQ/issues/1301
I had to write a cron script which will reload if it crashes.
But I did not want to reload copyq, if copyq exits during shutdown or restart
I ended up using
if ps aux | grep "Finder.app" | grep -v grep
then
echo "I am still running"
else
echo "I am in shutdown"
fi
To detect if system is in shutdown, (you can use Chrome.app or any other always running app depending on your need)
not exactly the solution, but helped me solve a similar problem that I was having
I'm opening an ssh-session to a remote server and execute a larger (around 1000 lines) bash-script on the remote machine. It involves several very CPU-intensive calls which run for up to three minutes each. To track the scripts progress it echoes messages placed at several points in the script.
In general the script runs smoothly. From time to time the script runs trough (the resulting file on the remote machine is correct) but the output to the terminal stops. Ctrl-C doesn't help, no prompt, just a frozen session. top in a separate session shows normal execution of the script.
My question: How keep the session alive?
local machine:
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.9
BuildVersion: 13A603
remote machine:
$ lsb_release -d
Description: Ubuntu 12.04.3 LTS
Personally, I would recommend using screen or tmux on the remote terminal for exactly this reason.
Those apps will allow the remote process to continue even if your local SSH session times out.
http://www.bangmoney.org/presentations/screen.html
http://tmux.sourceforge.net/
Start a screen on the remote machine and run your command from it:
screen -S largeScript
And then
./yourLargeScript.sh
Whenever your ssh session gets frozen, you can kill it with ~.
If you ssh again, you can grab back your screen by:
screen -dr largeScript
Make it log to a file instead (perhaps via syslog), and tail that file from wherever is convenient for you. This also helps detach the script so you can run it headless, from a cron job, etc. Also, if the log file has read access for others, they too can monitor it.
I have a master-workers architecture where the number of workers is growing on a weekly basis. I can no longer be expected to ssh or remote console into each machine to kill the worker, do a source control sync, and restart. I would like to be able to have the master place a message out on the network that tells each machine to sync and restart.
That's where I hit a roadblock. If I were using any sane platform, I could just do:
exec('ruby', __FILE__)
...and be done. However, I did the following test:
p Process.pid
sleep 1
exec('ruby', __FILE__)
...and on Windows, I get one ruby instance for each call to exec. None of them die until I hit ^C on the window in question. On every platform I tried this on, it is executing the new version of the file each time, which I have verified this by making simple edits to the test script while the test marched along.
The reason I'm printing the pid is to double-check the behavior I'm seeing. On windows, I am getting a different pid with each execution - which I would expect, considering that I am seeing a new process in the task manager for each run. The mac is behaving correctly: the pid is the same for every system call and I have verified with dtrace that each run is trigging a call to the execve syscall.
So, in short, is there a way to get a windows ruby script to restart its execution so it will be running any code - including itself - that has changed during its execution? Please note that this is not a rails application, though it does use activerecord.
After trying a number of solutions (including the one submitted by Byron Whitlock, which ultimately put me onto the path to a satisfactory end) I settled upon:
IO.popen("start cmd /C ruby.exe #{$0} #{ARGV.join(' ')}")
sleep 5
I found that if I didn't sleep at all after the popen, and just exited, the spawn would frequently (>50% of the time) fail. This is not cross-platform obviously, so in order to have the same behavior on the mac:
IO.popen("xterm -e \"ruby blah blah blah\"&")
The classic way to restart a program is to write another one that does it for you. so you spawn a process to restart.exe <args>, then die or exit; restart.exe waits until the calling script is no longer running, then starts the script again.
It seems to be impossible to completely disable the Sleep option in MacOSX so that a user cannot manually put the system to sleep.
Is there a way in Leopard (or even Snow Leopard) for AppleScript to catch the Sleep event and cancel it?
The answer to your problem is however a simple Apple-osx-Terminal command that prevents OSX to go idle:
$ pmset noidle
Preventing idle sleep (^C to exit)...
The only way to reset the no-sleeping is to issue a 'Control-C'.
See the man pages of pmset for more details.
This command has been deprecated in favor for
$ caffeinate -i
Which does roughly the same.
You can also run caffeinate for a pre-determined amount of time to prevent sleeping, say for 4 hours while you download something, and then run it in the background by adding & to it:
$ caffeinate -t 144000 &
You can't do this from user mode, because the power manager prevents it, so you'll need to use a kernel extension, such as InsomniaX.
Newer version(s) of OSX make it more possible to disable certain options according to https://apple.stackexchange.com/questions/35256/mac-os-x-lion-server-how-to-disable-sleep-restart-shutdown-options-for-users