Shell command to change macOS Time Machine update rate - macos

After seeing mathiasbynens' dotfiles, I've decided that I want to start building a script to configure all my system preferences to my liking.
As part of this, I need to decrease the Time Machine update rate (in order to reduce wear levels on my NAS' hard disk).
After doing some reading online [1], I have concluded that the file I need to edit is /System/Library/LaunchDaemons/com.apple.backupd-helper.plist.
I know that this is possible via the defaults command. Here is the section of the file I want to change:
$ defaults read /System/Library/LaunchDaemons/com.apple.backupd-helper LaunchEvents
{
"com.apple.xpc.activity" = {
"com.apple.backupd-auto" = {
AllowBattery = 1;
Delay = 3600;
GracePeriod = 1800;
Interval = 3600;
PowerNap = 1;
Priority = Utility;
Repeating = 1;
};
};
}
The problem is that, due to the dots (.) in the path to the Delay property, I cannot figure out how to specify said path directly.
I have tried LaunchEvents.\"com.apple.xpc.activity\", 'LaunchEvents."com.apple.xpc.activity"', and many variations thereof.
[1] https://staff.eecis.udel.edu/docs/timemachine/frequency/

I took a copy of /System/Library/LaunchDaemons/com.apple.backupd-helper.plist and saved it elsewhere as a.plist:
cp "/System/Library/LaunchDaemons/com.apple.backupd-helper.plist" /tmp/a.plist
Then I played around with PlistBuddy until I got this which seems to work:
/usr/libexec/PlistBuddy -c "Set :LaunchEvents:com.apple.xpc.activity:com.apple.backupd-auto:Interval 7200" /tmp/a.plist

Vaguely related to the original topic, it is way more flexible to disable time machine's auto scheduling and replace it with either TimeMachineEditor or simply create a launchd(8) rule. Eg. via LaunchControl

Related

How do I undo SetSysColors()?

So I executed:
int elements[2] = {COLOR_HIGHLIGHT,COLOR_HIGHLIGHTTEXT};
DWORD newColors[2];
newColors[0] = Color::IndianRed.ToArgb();
newColors[1] = Color::Maroon.ToArgb();
SetSysColors(2,elements,newColors);
I thought it might do what I hoped it wouldn't.. but it did so now everything I select looks like this:
What are the default values for my system to set it back to how it was? I am running Windows 10.
Quoting MSDN:
However, this function affects only the current session. The new colors are not saved when the system terminates.
Just reboot your machine.

How to measure total time spent in a function?

I have a utility function that I suspect is eating up a large portion of my application's execution time. Using Time Profiler to look at the call stack, this function takes up a large portion of the execution time of any function from which it is called. However, since this utility function is called from many different sources, I am having trouble determining if, overall, this is the best use of my optimization time.
How can I look at total time spent in this function during program execution, regardless of who called it?
For clarity, I want to combine the selected entries with all other calls to that function into a single entry:
For me, what does the trick is ticking "Invert Call Tree". It seems to sort "leaf" functions in the call tree in order of those that cumulate the most time, and allow you to see what calls them.
The checkbox can be found in the right panel, called "Display Settings" (If hidden: ⌘2 or View->Inspectors->Show Display Settings)
I am not aware of an instruments based solution but here is something you can do from code. Hope somebody provides an instruments solution but until then to get you going here goes.
#include <time.h>
//have this as a global variable to track time taken by the culprit function
static double time_consumed = 0;
void myTimeConsumingFunction(){
//add these lines in the function
clock_t start, end;
start = clock();
//main body of the function taking up time
end = clock();
//add this at the bottom and keep accumulating time spent across all calls
time_consumed += (double)(end - start) / CLOCKS_PER_SEC;
}
//at termination/end-of-program log time_consumed.
To see the totals for a particular function, follow these steps:
Profile your program with Time Profiler
Find and select any mention of the function of interest in the Call Tree view (you can use Edit->Find)
Summon the context menu over the selected function and 'Focus on calls made by ' (Or use Instrument->Call Tree Data Mining->Focus on Calls Made By )
If your program is multi-threaded and you want a total across all threads, make sure 'Separate by Thread' is not checked.
I can offer the makings of the answer you're looking for but haven't got this working within Instruments yet...
Instruments uses dtrace under the hood. dtrace allows you to respond to events in your program such as a function being entered or returned from. The response to each event can be scripted.
You can create a custom instrument with scripting in Instruments.
Here is a noddy shell script that launches dtrace outside of Instruments and records the time spent in a certain function.
#!/bin/sh
dtrace -c <yourprogram> -n '
unsigned long long totalTime;
self uint64_t lastEntry;
dtrace:::BEGIN
{
totalTime = 0;
}
pid$target:<yourprogram>:*<yourfunction>*:entry
{
self->lastEntry = vtimestamp;
}
pid$target:<yourprogram>:*<yourfunction>*:return
{
totalTime = totalTime + (vtimestamp - self->lastEntry);
/*#timeByThread[tid] = sum(vtimestamp - self->lastEntry);*/
}
dtrace:::END
{
printf( "\n\nTotal time %dms\n" , totalTime/1000000 )
}
'
What I haven't figured out yet is how to transfer this into instruments and get the results to appear in a useful way in the GUI.
I think you can call system("time ls"); twice and it will just work for you. The output will be printed on debug console.

Is there a way to make an existing cmd window execute commands?

So here is my situtation.
I am using the Windows OS. I am running a Matlab GUI that launches another executable at startup. The other executable runs in batch mode (runs in cmd in the background).
I want to make it so when a user clicks a button on the Matlab GUI, the other executable will run a command and remain open. Is this possible?
NOTE: I do not want to open a new cmd window, I want the existing one to execute commands.
Unfortunately it does not appear that Matlab has the ability you are looking for, at least not directly. I found a post which does explain how to do it with the help of .NET though, which is fortunate since you are on the Windows platform: http://www.mathworks.com/matlabcentral/answers/72356-using-matlab-to-send-strings-to-the-stdin-of-another-console-application
I have copied a lot of this from that post
function lh = task()
% Initialize the process and its StartInfo properties.
% The sort command is a console application that
% reads and sorts text input.
process = System.Diagnostics.Process;
process.StartInfo.FileName = 'sort.exe';
process.EnableRaisingEvents = true;
process.StartInfo.CreateNoWindow = true;
% Set UseShellExecute to false for redirection.
process.StartInfo.UseShellExecute = false;
%Redirect the standard output of the sort command.
process.StartInfo.RedirectStandardOutput = true;
% Set our event handler to asynchronously read the sort output.
lh = process.addlistener('OutputDataReceived',#sortOutputHandler);
% Redirect standard input as well. This stream
% is used synchronously.
process.StartInfo.RedirectStandardInput =true;
% Start the process.
process.Start();
%Use a stream writer to synchronously write the sort input.
ProcessStreamWriter = process.StandardInput;
% Start the asynchronous read of the sort output stream.
process.BeginOutputReadLine();
%Prompt the user for 4 input text lines. Write each
%line to the redirected input stream of the sort command.
numInputLines = 0;
while(numInputLines ~= 4)
inputText = input('Enter a text line (or press the Enter key to stop):', 's');
numInputLines = numInputLines + 1;
if(~isempty(inputText))
ProcessStreamWriter.WriteLine(inputText);
end
end
disp('end of input stream');
%end the inputr stream to the sort command
ProcessStreamWriter.Close();
% wait for the sort process to write the sorted text lines
process.WaitForExit();
process.Close();
end
For handling any output from the CMD you need:
function processOutputHandler(obj,event)
%collect the sort command output and print in command window
if(~isempty(event.Data))
disp(event.Data);
end
end
You can use a stream writer to synchronously write the sort input.
processStreamWriter = process.StandardInput;
Again, I have taken this from the previously mentioned post so I can't take any credit for the code, but I do think it will be able to accomplish what you are looking for. Unfortunately, I am pretty sure this will accomplish what you need. I don't have Matlab on a Windows platform at the moment or I would test this. If you need information on using .NET code in MATLAB (its not immediately clear if you need to add some stuff to establish the .NET interface) MathWorks provides some documentation on it: http://www.mathworks.com/help/matlab/matlab_external/using-net-from-matlab-an-overview.html
Hopefully this helps, or gets you started. Let me know if there's anything else I missed.
You can approach this from the ansys side. Start it with -B-R to read a python script.
From there, you can establish some two-way protocol, for example polling files or, better, by running a web server from python.
Then you can communicate from matlab with that running instance of ansys. If you opt for a web server, you use MATLABs urlread().
Setting up a web-server with python is easy, but you have to learn how to dispatch commands to the hosting ansys application.

Matlab - signal after command completion

Is there a way to set matlab to come to the foreground of the windows when the command in complete? I can see it happening by executing a dos() but I'm unaware how window management works? Maybe there is a better way? Someone?
Two options. Neither exactly what you are asking for.
Option 1: Open a new figure.
figure();
imagesc(processingDoneSplashImage);
If you want to get fancy, put this in a script, with a timer, and flash the image between bright green, and bright red....
Option 2: My solution to your problem. (I find popping up windows extremely annoying.) I put this function call at the end of my long running scripts, and the computer tells me when it's done processing....
function [ ] = matSpeak( textToSpeak )
%matSpeak takes some text, and outputs onto the speaker the text,
% using the .Net SpeechSynthesizer.
% This only works on Windoze.
if ~exist('textToSpeak','var')
textToSpeak = 'Your processing has completed.';
end
NET.addAssembly('System.Speech');
speak = System.Speech.Synthesis.SpeechSynthesizer;
speak.Volume = 100;
speak.Speak(textToSpeak);
end
Why not just use Growl for your notification windows?
cmd = ['/usr/local/bin/growlnotify -m ' messagestr];
system(cmd);
Of course with Windows you need to fix the path to the growlnotify binary.
Source: http://www.mathworks.com/matlabcentral/newsreader/view_thread/259142
A wrapper with lots of features: Send a notification to Growl on MATLAB Exchange
Many more examples: https://www.google.com/search?q=growl+matlab

Is it possible to reasonably workaround an antivirus scanning the working directory?

My Win32 application performs numerous disk operations in a designated temporary folder while functioning, and seriously redesigning it is out of the question.
Some clients have antivirus software that scans the same temporary directory (it simply scans everything). We tried to talk them into disabling it - it doesn't work, so it's out of the question either.
Every once in a while (something like once for every one thousand file operations) my application tries to perform an operation on a file which is at that very time opened by the antivirus and is therefore locked by the operating system. A sharing violation occurs and causes an error in my application. This happens about once in three minutes on average.
The temporary folder can contain up to 100k files in most typical scenarios, so I don't like the idea of having them open at all times because this could cause running out of resources on some edge conditions.
Is there some reasonable strategy for my application to react to situations when a needed file is locked? Maybe something like this?
for( int i = 0; i < ReasonableNumber; i++ ) {
try {
performOperation(); // do useful stuff here
break;
} catch( ... ) {
if( i == ReasonableNumber - 1 ) {
throw; //not to hide errors if unlock never happens
}
}
Sleep( ReasonableInterval );
}
Is this a viable strategy? If so, how many times and how often should my application retry? What are better ideas if any?
A virusscanner that locks files while it's scanning them is quite bad. Clients who have virusscanners this bad need to have their brains replaced... ;-)
Okay, enough ranting. If a file is locked by some other process then you can use a "try again" strategy like you suggest. OTOH, do you really need to close and then re-open those files? Can't you keep them open until your process is done?
One tip: Add a delay (sleep) when you try to re-open the file again. About 100 ms should be enough. If the virusscanner keeps the file open that long then it's a real bad scanner. Clients with scanners that bad deserve the exception message that they'll see.
Typically, try up to three times... -> Open, on failure try again, on second failure try again, on third failure just crash.
Remember to crash in a user-friendly way.
I've had experience with antivirus software made by both Symantec and AVG which resulted in files being unavailable for open.
A common problem we experienced back in the 2002 time frame with Symantec was with MSDev6 when a file was updated in this sequence:
a file is opened
contents are modified in memory
application needs to commit changes
application creates new tmp file with new copy of file + changes
application deletes old file
application copies tmp file to old file name
application deletes the tmp file
The problem would occur between step 5 and step 6. Symantec would do something to slowdown the delete preventing the creation of a file with the same name (CreateFile returned ERROR_DELETE_PENDING). MSDev6 would fail to notice that - meaning step 6 failed. Step 7 still happened though. The delete of the original would eventually finish. So the file no longer existed on disk!
With AVG, we've been experiencing intermittent problems being able to open files that have just been modified.
Our resolution was a try/catch in a reasonable loop as in the question. Our loop count is 5.
If there is the possibility that some other process - be it the antivirus software, a backup utility or even the user themselves - can open the file, then you must code for that possibility.
Your solution, while perhaps not the most elegant, will certainly work as long as ReasonableNumber is sufficiently large - in the past I've used 10 as the reasonable number. I certainly wouldn't go any higher and you could get away with a lower value such as 5.
The value of sleep? 100ms or 200ms at most
Bear in mind that most of the time your application will get the file first time anyway.
Depends on how big your files are, but for 10s to 100s of Kb I find that 5 trys with 100ms (0.1 seconds) to be sufficient. If you still hit the error once in a while, double the wait, but YMMV.
If you have a few places in the code which needs to do this, may I suggest taking a functional approach:
using System;
namespace Retry
{
class Program
{
static void Main(string[] args)
{
int i = 0;
Utils.Retry(() =>
{
i = i + 1;
if (i < 3)
throw new ArgumentOutOfRangeException();
});
Console.WriteLine(i);
Console.Write("Press any key...");
Console.ReadKey();
}
}
class Utils
{
public delegate void Retryable();
static int RETRIES = 5;
static int WAIT = 100; /*ms*/
static public void Retry( Retryable retryable )
{
int retrys = RETRIES;
int wait = WAIT;
Exception err;
do
{
try
{
err = null;
retryable();
}
catch (Exception e)
{
err = e;
if (retrys != 1)
{
System.Threading.Thread.Sleep(wait);
wait *= 2;
}
}
} while( --retrys > 0 && err != null );
if (err != null)
throw err;
}
}
}
Could you change your application so you don't release the file handle? If you hold a lock on the file yourself the antivir application will not be able to scan it.
Otherwise a strategy such as yours will help, a bit, because it only reduces the probability but it doesn't solve the problem.
Tough problem. Most ideas that I have go into a direction that you don't want (e.g. redesign).
I don't know how many files you have in your directory, but if it's not that much you may be able to work around your problem by keeping all files open and locked while your program runs.
That way the virus scanner will have no chance to interrupt your file-accesses anymore.

Resources