Communication between scripts running on 2 different users ...

Hi, Robert.

My handler doesn’t write text to the file. It writes data for an AppleScript record. If you try to read these data as text, you’ll see all sorts of weird stuff. Most of the bytes don’t represent text characters but numbers involved in the structure of the record. Many of them are invisible in a text editor and they’re probably what caused the problem when you tried to include them in your post above.

The file has to be read with the ‘read’ command, using the parameter ‘as record’. The result is then a functional AppleScript record.

I’ve assumed that you’ll be using an AppleScript to analyse the file contents and decide when to put the computer to sleep. If that’s true, a record should make things slightly simpler. If not, my suggestion won’t suit your needs.

Neil,

I am scripting with AS, so your scripts should be good. I have modified the ownership of the Inactivity.log file to «Read/Write» for everybody. Because of weird/incomprehensible characters appearing in the text editor version of the Inactivity.log file, I am unable to verify the result other than by running the second part of your script. When running it it runs perfectly.

Thank you very much for that surgical work. You wrote a piece of script that, I have to admit, I mostly don’t understand but that I can appreciate the result.

Regards.

Robert

P.S. Can the ownership of that file be defined and managed by the script ?

Hi Neil,

I have integrated your handlers in my idle handler. I also trashed the last version of the «ActivityLog» file to fresh start a new file. My idle handler ended with an «end of file» error message. Does your handler create a new log file if it does not exist ?

Regards.

Robert

Hi, Robert.

Yes. The ‘open for access’ command creates the file if it doesn’t already exist.

An end-of-file error is caused by trying to read beyond the end of the file, so one or both of the following may be true:

  1. Your script might be trying to read the file before anything’s been written to it. (Unlikely if my handler created the file.)
  2. Your script may previously have opened and used a read-only access to the file which it didn’t then close. The read command will then be trying to read from where the previous read left off (ie. at the end of the file).

I’ve no experience of running scripts simultaneously in different users, but it’s conceivable that there may be conflicts if they both try to access the file at the same time. One script might try to read the file in the split second between the other emptying it and writing new data do it.

But since we’re now writing and reading a record, I don’t think it’s absolutely necessary to empty the file before writing to it. A record containing only integer values is unlikely to get any shorter and, even if it does, ‘read’ will only read as much data as it needs to complete the shorter record. ‘set eof fRef to 0’ can therefore be omitted from my handler, but the following ‘write’ will then have to start explicitly at the beginning of the file. In theory, only one application can have write-permission access to a file at any one time, so I’ve added an extra ‘try’ block in case both applets try to get write permission at the same time. The handler in the unlucky one will then simply exit without doing anything.

on updateInactivityLog(n) -- n is the number of processes of the current user.
	-- Create a single-property record with the current user name as the label and n as the value.
	set newRecord to (run script "{|" & (system attribute "USER") & "|:" & n & "}")
	-- Open the log file with write permission. If write-permission access is denied, do nothing.
	try
		set fRef to (open for access file ((path to "sdat" as Unicode text) & "Inactivity.log") with write permission)
		try
			-- If the file's not empty, concatentate its existing record contents to newRecord.
			-- The normal precedence rules for record concatenation apply.
			if ((get eof fRef) > 0) then set newRecord to newRecord & (read fRef as record)
			-- Write newRecord back to the log file.
			write newRecord to fRef starting at 1
		end try
		-- Close the log file.
		close access fRef
	end try
end updateInactivityLog

Er ” Neil. :wink:

Hi Nigel,

You were right. Running the handler simultaneously on 2 users, I got into a «Network file permission error». Is it possible not to try accessing the file if it is busy ?

Regards.

Robert

Hmm. I see. When the file’s created, its permissions are set so that anyone can read it but only the user that created it can write to it.

Manually, this is easily fixed:
In the user that creates the file, select the file in the Finder and type Command-i. At the bottom of the information window that opens, there’s an “Ownership & Permissions” section. At the bottom of this, there’s a pop-up menu called “Others” which you should set to “Read & Write” (or the equivalent in your own language). Once that’s done, it shouldn’t be necessary to do it again unless the file’s deleted and needs to be recreated.

It’s probably possible to set the permissions with a shell script when the file’s created, but I don’t know how to do that at the moment.

The command line program is chmod (CHange MODe, the permission bits are part of the “mode”). The invocation to grant everyone read and write access is chmod a+rw filename(s) (the filenames are POSIX paths, of course). A more exact equivalent to the menu item you mentioned would be o+rw, but a+rw also covers the group perms for an unlikely corner case where the accessing user is a member of the file’s group but the file does not grant group perms.

Hi,

Nigel … Just forgot to change the ownership settings after creating a new log file … I thought it was related to the fact you pointed out about 2 scripts trying to have access to the same file. I changed manually the ownership. I think it should do the job. Seems to be working OK.

Chrys, I am not experience at all in shell scripting. So if you can give me exactly the script I will give it a try. Otherwise I will have to stick with doing it manually.

Thank you both. Regards.

Robert

Does this help you?


set theScript to "chmod a+rw  " & quoted form of POSIX path of (choose file)
set theResult to do shell script theScript
if "" ≠ theResult then display dialog "not good: " & theResult

:smiley:

Thanks for the information, Chris! (And SwissalpS.) Here’s a version of the handler that liberalises the permissions if it thinks the log file’s brand new:

on updateInactivityLog(n) -- n is the number of processes of the current user.
	set logPath to (path to "sdat" as Unicode text) & "Inactivity.log"
	
	-- Create a single-property record with the current user name as the label and n as the value.
	set newRecord to (run script "{|" & (system attribute "USER") & "|:" & n & "}")
	-- Open the log file with write permission. If write-permission access is denied, do nothing.
	try
		set fRef to (open for access file logPath with write permission)
		try
			if ((get eof fRef) is 0) then
				-- If the file's empty, assume it's just been created.
				-- Set its permissions to allow writing by other users.
				do shell script ("chmod a+rw " & quoted form of POSIX path of logPath)
			else
				-- If the file's not empty, concatentate its existing record contents to newRecord.
				-- The normal precedence rules for record concatenation apply.
				set newRecord to newRecord & (read fRef as record)
			end if
			-- Write newRecord back to the log file.
			write newRecord to fRef starting at 1
		end try
		-- Close the access to the log file.
		close access fRef
	end try
end updateInactivityLog

Hi Nigel,

Thanks for your work … I will try it out and keep you informed.

Regards.

Robert

Hi Nigel,

Everything as been running for a few weeks now, without any problem. My InactivityMonitoring handler works great. I thank you very much for your help having these 2 scripts talk together.

Yesterday, I decided that I would make my «ActivityLog» file invisible. The scripts stopped talking … I thought that making it invisible would not change anything. Is it possible to make that file invisible ?

Regards.

Hi, Robert.

It works for me. How are you making your file invisible?

Good evening Nigel,

I am using Secret Folder v 8.0. I think the problem is created because the «ActivityLog» file is read/created by 2 different user simultaneously. Did you test with 2 user ?

I don’t understand what is happenning. When the file in made invisible on one user, the other user seems to be creating another visible one. On the other hand, the system seems to be changing the name of the first file by calling it «ActivityLog2» because there is 2 «ActivityLog» file.

That is what I see, but I am not sure what is really happening.

Does this help you ?

Regards.

Robert

Hi Robert,

after you make the files invisible did you check the permissions?
In your script you change them, make sure that those flags are the same.
Maybe SecretFolder changes the owner or some other flag.

Just a thought.

Hi Nigel and SwissalpS,

There was a hidden «ActivityLog» file. I had trouble seeing it. I used the «Super Get Info» utility and got it visible again. That file had permission restrictions (only «read» for groups and others). I am mostly sure that originaly I changed the file’s permissions to allow «read and write» to all.

If I also recall correctly, Nigel’s script for modifying the «ActivityLog» file recreates the file when needed or if missing. What will the permissions of that file be ? If the script recreates a file that does not have to good permissions, is it not better to get an error message and modify it manually ?

While I thought everything was going well, because of my limited understanding of the script’s details, maybe there is still something missing.

What do you understand from what I say ? Am I precise enough to push the problem’s resolving further ?

Regards.

Robert

I restarted everything from the beginning. I quitted the script on each user. I trashed the «ActivityLog» file. I restarted the script on only one user until the «ActivityLog» file is created. The permissions of that file were «read only» for groups and others, so I manually changed it to «read and write».

I then made it invisible and started the script on the second user. Later I gave a look in the shared folder (ActivityLog’s folder) and there was a visible ActivityLog file. With SecretFolder I could see 2 ActivityLog files: one visible and the other invisible. The visible one had only «read» permissions and the invisible one still had «read and write» permissions.

One of the scripts does recognize the invisible file perhaps ? When changing the permissions should I also change the owner to system ?

Is there a solution to this ? Is it possible, when creating the file, to set the ownership and permissions by script ?

Thanks again for all your help.

Robert

I simply changed the file name in the script(s) to one beginning with a dot ” eg. “.Inactivity.log”. The file was created invisible to the Finder but was still accessible to both scripts.

Hi Nigel,

Thanks again. What a simple trick :):):slight_smile: Never thought it would be that simple to create an invisible file.

Is it possible to modify the ownership and the permissions by script or with shellscripting ?

Regards

Hi, Robert. The script already does that.